gpt4 book ai didi

Can Dapper Mappings Be Automated with Attributes?(Dapper映射可以使用属性自动执行吗?)

转载 作者:bug小助手 更新时间:2023-10-28 10:34:03 26 4
gpt4 key购买 nike



In my webapi dotnet7 application, I utilize Dapper for database operations. Additionally, I employ a solution found on StackOverflow for mapping database columns to class properties using the Column attribute, as shown in the following example:

在我的webapi dotnet7应用程序中,我使用Dapper进行数据库操作。此外,我使用StackOverflow上的一个解决方案,使用Column属性将数据库列映射到类属性,如下面的示例所示:


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

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

This Column attribute is sourced from the ColumnAttributeTypeMapper.cs file, which contains the custom type mapper logic. Here's an excerpt:

该列属性来自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);
}
}

}

To ensure Dapper recognizes these mappings, I currently add a SetTypeMap call for each model in the Program.cs file, which can lead to merge conflicts. For example:

为了确保Dapper能够识别这些映射,我目前在Program.cs文件中为每个模型添加了一个SetTypeMap调用,这可能会导致合并冲突。例如:


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

Is there a way to automate the registration of these mappings for all models in the project? Perhaps by using an attribute, such as [DapperMapper], to associate each model with Dapper?

有没有办法为项目中的所有模型自动注册这些映射?也许可以使用一个属性,如[DapperMapper],将每个模型与Dapper关联起来?


Please advise on a more automated approach for registering Dapper mappings.

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


更多回答
优秀答案推荐

The short answer currently is "no"; Dapper already does a ton of reflection, and it isn't hugely desirable to add more.

目前的简短答案是“不”;Dapper已经做了大量的反思,添加更多内容并不是很理想。


However; in the upcoming (incomplete, depends at least on net9 for build tool support) DapperAOT era, I do hope to incorporate something like this; in particular:

然而,在即将到来的DapperAOT时代(不完整,至少依赖于net9的构建工具支持),我确实希望加入这样的东西;特别是:



  • there is already a [DbValue(...)] that allows a Name to be specified (works both both column and parameter names)

  • I intend to add support for the well-known [System.ComponentModel.DataAnnotations.Schema.ColumnAttribute] attribute, (perhaps via a global [UseColumnAttribute] marker, to avoid surprises - perhaps even with a build warning if you have [Column(...)] but don't have an explicit [UseColumnAttribute]/[UseColumnAttribute(false)])


but: that's at least a few months out (can't release until at least November, and: I haven't even implemented [Column] yet)

但是:这至少还需要几个月的时间(至少要到11月才能发布,而且:我甚至还没有实现[专栏])


I've logged https://github.com/DapperLib/DapperAOT/issues/36 for tracking

我已登录https://github.com/DapperLib/DapperAOT/issues/36进行跟踪


更多回答

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com