默认情况下,如何排除继承自 ClassMapper<T> 的 类 中的所有虚拟属性?
How to exclude all virtual properties from classes inheritted from ClassMapper<T> by default?
我有很多 POCO classes,每个都包含几个虚拟属性。像这样:
public class Policy
{
public int Id { get; set; }
public int EntityId { get; set; }
public int ProgramId { get; set; }
public string PolicyNumber { get; set; }
public DateTime EffectiveDate { get; set; }
public DateTime ExpirationDate { get; set; }
public virtual Entity Entity{ get; set; }
public virtual Program Program { get; set; }
public virtual ICollection<Transaction> Transactions { get; set; }
}
为了让 Dapper.Extensions
工作,我需要为每个 class 编写一个映射,这很好。我的问题是,如果 class 中有任何 virtual
属性,则需要将它们显式标记为 ignored,我总是忘记这样做。
public sealed class PolicyMapper : BaseMapper<Policy>
{
public PolicyMapper()
{
Map(p => p.Entity).Ignore();
Map(p => p.Program).Ignore();
Map(p => p.Transactions).Ignore();
AutoMap();
}
}
如果 Dapper.Extensions
库在映射到 POCO class 时会自动排除虚拟属性(如果有),那对我来说会很棒。 Automapper
有一个扩展,可以做类似的事情 (link)。 Dapper.Extensions
图书馆有办法做到这一点吗?可能是这样的:
public sealed class PolicyMapper : BaseMapper<Policy>
{
public PolicyMapper()
{
IgnoreAllVirtual();
AutoMap();
}
}
我找到了自己的解决方案。由于我所有的映射 classes 都派生自 BaseMapper class,我决定覆盖将排除虚拟属性的 AutoMap() 方法:
public class BaseMapper<T> : ClassMapper<T> where T : BaseClass
{
public BaseMapper()
{
}
protected override void AutoMap()
{
CustomAutoMap(null);
}
private void CustomAutoMap(Func<Type, PropertyInfo, bool> canMap)
{
Type type = typeof(T);
bool hasDefinedKey = Properties.Any(p => p.KeyType != KeyType.NotAKey);
PropertyMap keyMap = null;
foreach (var propertyInfo in type.GetProperties())
{
// Exclude virtual properties
if (propertyInfo.GetGetMethod().IsVirtual)
{
continue;
}
if (Properties.Any(p => p.Name.Equals(propertyInfo.Name, StringComparison.InvariantCultureIgnoreCase)))
{
continue;
}
if ((canMap != null && !canMap(type, propertyInfo)))
{
continue;
}
PropertyMap map = Map(propertyInfo);
if (!hasDefinedKey)
{
if (string.Equals(map.PropertyInfo.Name, "id", StringComparison.InvariantCultureIgnoreCase))
{
keyMap = map;
}
if (keyMap == null && map.PropertyInfo.Name.EndsWith("id", true, CultureInfo.InvariantCulture))
{
keyMap = map;
}
}
}
if (keyMap != null)
{
keyMap.Key(PropertyTypeKeyTypeMapping.ContainsKey(keyMap.PropertyInfo.PropertyType)
? PropertyTypeKeyTypeMapping[keyMap.PropertyInfo.PropertyType]
: KeyType.Assigned);
}
}
}
}
我有很多 POCO classes,每个都包含几个虚拟属性。像这样:
public class Policy
{
public int Id { get; set; }
public int EntityId { get; set; }
public int ProgramId { get; set; }
public string PolicyNumber { get; set; }
public DateTime EffectiveDate { get; set; }
public DateTime ExpirationDate { get; set; }
public virtual Entity Entity{ get; set; }
public virtual Program Program { get; set; }
public virtual ICollection<Transaction> Transactions { get; set; }
}
为了让 Dapper.Extensions
工作,我需要为每个 class 编写一个映射,这很好。我的问题是,如果 class 中有任何 virtual
属性,则需要将它们显式标记为 ignored,我总是忘记这样做。
public sealed class PolicyMapper : BaseMapper<Policy>
{
public PolicyMapper()
{
Map(p => p.Entity).Ignore();
Map(p => p.Program).Ignore();
Map(p => p.Transactions).Ignore();
AutoMap();
}
}
如果 Dapper.Extensions
库在映射到 POCO class 时会自动排除虚拟属性(如果有),那对我来说会很棒。 Automapper
有一个扩展,可以做类似的事情 (link)。 Dapper.Extensions
图书馆有办法做到这一点吗?可能是这样的:
public sealed class PolicyMapper : BaseMapper<Policy>
{
public PolicyMapper()
{
IgnoreAllVirtual();
AutoMap();
}
}
我找到了自己的解决方案。由于我所有的映射 classes 都派生自 BaseMapper class,我决定覆盖将排除虚拟属性的 AutoMap() 方法:
public class BaseMapper<T> : ClassMapper<T> where T : BaseClass
{
public BaseMapper()
{
}
protected override void AutoMap()
{
CustomAutoMap(null);
}
private void CustomAutoMap(Func<Type, PropertyInfo, bool> canMap)
{
Type type = typeof(T);
bool hasDefinedKey = Properties.Any(p => p.KeyType != KeyType.NotAKey);
PropertyMap keyMap = null;
foreach (var propertyInfo in type.GetProperties())
{
// Exclude virtual properties
if (propertyInfo.GetGetMethod().IsVirtual)
{
continue;
}
if (Properties.Any(p => p.Name.Equals(propertyInfo.Name, StringComparison.InvariantCultureIgnoreCase)))
{
continue;
}
if ((canMap != null && !canMap(type, propertyInfo)))
{
continue;
}
PropertyMap map = Map(propertyInfo);
if (!hasDefinedKey)
{
if (string.Equals(map.PropertyInfo.Name, "id", StringComparison.InvariantCultureIgnoreCase))
{
keyMap = map;
}
if (keyMap == null && map.PropertyInfo.Name.EndsWith("id", true, CultureInfo.InvariantCulture))
{
keyMap = map;
}
}
}
if (keyMap != null)
{
keyMap.Key(PropertyTypeKeyTypeMapping.ContainsKey(keyMap.PropertyInfo.PropertyType)
? PropertyTypeKeyTypeMapping[keyMap.PropertyInfo.PropertyType]
: KeyType.Assigned);
}
}
}
}