Dapper 映射可以通过属性实现自动化吗?

问题描述 投票:0回答:1

在我的 webapi dotnet7 应用程序中,我使用 Dapper 进行数据库操作。此外,我采用了 StackOverflow 上找到的解决方案,使用

Column
属性将数据库列映射到类属性,如以下示例所示:

public class Customer
{
    public int CustomerID { get; set; }

    [Column(Name = "Customer_Name")]
    public string Name{ get; set; }
}

此 Column 属性源自

ColumnAttributeTypeMapper.cs
文件,其中包含自定义类型映射器逻辑。摘录如下:

namespace YourNamespace
{
    /// <summary>
    /// Uses the Name value of the <see cref="ColumnAttribute"/> specified to determine
    /// the association between the name of the column in the query results and the member to
    /// which it will be extracted. If no column mapping is present all members are mapped as
    /// usual.
    /// </summary>
    /// <typeparam name="T">The type of the object that this association between the mapper applies to.</typeparam>
    public class ColumnAttributeTypeMapper<T> : FallbackTypeMapper
    {
        public ColumnAttributeTypeMapper()
            : base(new SqlMapper.ITypeMap[]
                {
                    new CustomPropertyTypeMap(
                       typeof(T),
                       (type, columnName) =>
                           type.GetProperties().FirstOrDefault(prop =>
                               prop.GetCustomAttributes(false)
                                   .OfType<ColumnAttribute>()
                                   .Any(attr => attr.Name == columnName)
                               )
                       ),
                    new DefaultTypeMap(typeof(T))
                })
        {
        }
    }
    
        [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class ColumnAttribute : Attribute
    {
        public string Name { get; set; }
    }

    public class FallbackTypeMapper : SqlMapper.ITypeMap
    {
        private readonly IEnumerable<SqlMapper.ITypeMap> _mappers;

        public FallbackTypeMapper(IEnumerable<SqlMapper.ITypeMap> mappers)
        {
            _mappers = mappers;
        }


        public ConstructorInfo FindConstructor(string[] names, Type[] types)
        {
            foreach (var mapper in _mappers)
            {
                try
                {
                    ConstructorInfo result = mapper.FindConstructor(names, types);
                    if (result != null)
                    {
                        return result;
                    }
                }
                catch (NotImplementedException)
                {
                }
            }
            return null;
        }

        public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName)
        {
            foreach (var mapper in _mappers)
            {
                try
                {
                    var result = mapper.GetConstructorParameter(constructor, columnName);
                    if (result != null)
                    {
                        return result;
                    }
                }
                catch (NotImplementedException)
                {
                }
            }
            return null;
        }

        public SqlMapper.IMemberMap GetMember(string columnName)
        {
            foreach (var mapper in _mappers)
            {
                try
                {
                    var result = mapper.GetMember(columnName);
                    if (result != null)
                    {
                        return result;
                    }
                }
                catch (NotImplementedException)
                {
                }
            }
            return null;
        }
        
        
        public ConstructorInfo FindExplicitConstructor()
        {
            return _mappers
                .Select(mapper => mapper.FindExplicitConstructor())
                .FirstOrDefault(result => result != null);
        }
    }
  
}

为了确保 Dapper 识别这些映射,我目前为

SetTypeMap
文件中的每个模型添加了
Program.cs
调用,这可能会导致合并冲突。例如:

Dapper.SqlManager.SetTypeMap(typeof(Customer), new ColumnAttributeTypeMapper<Customer>);

有没有办法自动为项目中的所有模型注册这些映射?也许通过使用属性(例如

[DapperMapper]
)将每个模型与 Dapper 相关联?

请提供有关注册 Dapper 映射的更自动化方法的建议。

c# .net dapper
1个回答
0
投票

目前简短的回答是“不”; Dapper 已经进行了大量的反射,并且不太需要添加更多反射。

但是

;在即将到来的(不完整,至少依赖于 net9 构建工具支持)DapperAOT 时代,我do希望纳入这样的东西;特别是: 已经有一个 [DbValue(...)]

允许指定
    Name
  • (同时适用于列和参数名称)
    我打算
    添加
    对众所周知的
  • [System.ComponentModel.DataAnnotations.Schema.ColumnAttribute]
  • 属性的支持(可能通过全局[UseColumnAttribute]标记,以避免意外 - 如果您
    [Column(...)]
    不',甚至可能会出现构建警告) t 有明确的
    [UseColumnAttribute]
    /[UseColumnAttribute(false)])
    
    
    但是:这至少需要几个月的时间(至少要到 11 月才能发布,并且:我什至还没有实施
    [Column]

我已登录

https://github.com/DapperLib/DapperAOT/issues/36
进行跟踪

© www.soinside.com 2019 - 2024. All rights reserved.