我正在重写遗留系统以使用实体框架。旧系统的实体的一半属性映射到数据库列,另一半则没有。为了指示必须映射某个属性,该属性用 [Field] 属性进行修饰。所有其他属性都被忽略。
这与 EF 的做法相反。按照惯例,EF 会将所有带有 getter 和 setter 的公共属性映射到数据库字段,除非该属性使用 [NotMapped] 数据注释进行修饰,或者在模型创建时使用 Fluent API 对该属性调用了 Ignore。
我想覆盖 EF 约定以像旧系统一样工作。即忽略没有 FieldAttribute 的属性。我知道这可以通过将 [NotMapped] 添加到所有属性来完成,但我正在寻找一种动态执行此操作的方法,这样我就不必更改每个实体(有数百个)
我可以看到没有系统约定可以删除或覆盖此内容
https://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.conventions.aspx https://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.conventions.aspx
我尝试使用以下代码来使用反射调用忽略,但没有成功:
modelBuilder.Properties().Configure((configuration) =>
{
var attributes = configuration.ClrPropertyInfo.GetCustomAttributes(inherit: false);
var fieldAttribute = attributes.FirstOrDefault(x => x.GetType() == typeof(FieldAttribute) || x.GetType() == typeof(KeyAttribute));
if (fieldAttribute == null)
{
var entityMethod = modelBuilder.GetType().GetMethod("Entity");
var entityConfiguration = entityMethod.MakeGenericMethod(configuration.ClrPropertyInfo.ReflectedType).Invoke(modelBuilder, new object[] { });
MethodInfo ignoreMethod = entityConfiguration.GetType()
.GetMethod("Ignore")
.MakeGenericMethod(configuration.ClrPropertyInfo.PropertyType);
var parameter = Expression.Parameter(configuration.ClrPropertyInfo.ReflectedType);
var memberExpression = Expression.Property(parameter, configuration.ClrPropertyInfo.Name);
var lambdaExpression = Expression.Lambda(memberExpression, parameter);
ignoreMethod.Invoke(entityConfiguration, new[] { lambdaExpression });
}
});
这看起来很有效,因为该属性已添加到实体配置的忽略列表中。但 EF 仍然尝试将属性映射到不存在的 DB 字段并引发 Invalid column 异常。
还有人有其他想法吗?
我找到了解决问题的办法。如果我从 TypeConventionConfiguration 而不是 PropertyConventionConfiguration 得到这个,它就可以工作。我上面的代码可能有一些错误。这样我需要使用更少的反射......
modelBuilder.Types().Configure((entityConfiguration) =>
{
const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly;
foreach (var propertyInfo in entityConfiguration.ClrType.GetProperties(bindingFlags))
{
var attributes = propertyInfo.GetCustomAttributes(inherit: false);
var fieldAttribute = attributes.FirstOrDefault(x => x.GetType() == typeof(FieldAttribute) || x.GetType() == typeof(KeyAttribute));
if (fieldAttribute == null)
{
entityConfiguration.Ignore(propertyInfo);
}
}
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)