我正在使用EntityFramework - Code First,DBContext和POCO类。
在运行时,如何检测属性属于数据库中生成的字段,标记为.HasDatabaseGeneratedOption,.IsRowVersion(readonly?)等。
我看着var xxx = Entity.GetType().GetProperty("ID").Get
......,没有运气。
public partial class OnMuhasebeContext : DbContext
{
public bool IsDatabaseGeneratedProperty <?>(...)
{
// Parameters :
// We know all poco classes of course
// also parameters can be instance type
}
}
更新:
请将“数据库生成”视为“由数据库生成的值的字段”,并在模型中标记以反映该情况。
这些属性都属于数据库生成的字段,并使用Fluent API标记为identity和RowVersion。
public class POCOMap : EntityTypeConfiguration<POCO>
{
public POCOMap()
{
// Primary Key
this.HasKey(t => t.ID);
this.Property(t => t.RowVersion)
.IsFixedLength()
.HasMaxLength(8)
.IsRowVersion();
}
}
重点:如何使用Fluent API或Data Annotions在模型或代码优先模型中标记属性。数据库本身并不重要,就像实体框架背后的哲学一样。
答案 0 :(得分:0)
好吧,我想我得到了你想要达到的目标。
可悲的是,您无法开箱即用EntityTypeConfiguration
。
但是,您还可以做其他事情。您可以使用自己的Attribute
并将其放在具有数据库生成值的属性上。
一个例子:
我们的自定义属性:
[AttributeUsage(AttributeTargets.Property)]
public class GeneratedByDatabaseAttribute : Attribute
{
}
使用属性的非常简单的poco:
public class SimplePoco
{
[GeneratedByDatabase]
public int Id { get; set; }
[GeneratedByDatabase]
public int RowVersion { get; set; }
public string Name { get; set; }
}
这就是魔术发生的地方。我正在使用GetPropertyInfo
从lambda表达式中获取成员。这个方法到目前为止还不完整,但是有足够的样本全部是arround stackoverflow。
简而言之:我获取了给定媒体资源的PropertyInfo
,并检查它是否具有我们的自定义GeneratedByDatabaseAttribute
属性。
public class MyContext : DbContext
{
public bool IsDatabaseGeneratedProperty<TSource>(Expression<Func<TSource, object>> propertyExpression)
{
var property = GetPropertyInfo(propertyExpression);
var attribute = property.GetCustomAttribute<GeneratedByDatabaseAttribute>();
return attribute != null;
}
public PropertyInfo GetPropertyInfo<TSource>(Expression<Func<TSource, object>> propertyLambda)
{
var member = propertyLambda.Body as MemberExpression;
if (member == null)
{
var ubody = (UnaryExpression)propertyLambda.Body;
member = ubody.Operand as MemberExpression;
}
return member.Member as PropertyInfo;
}
}
这是我用LinqPad测试它的方式:
void Main()
{
var context = new MyContext();
var result = context.IsDatabaseGeneratedProperty<SimplePoco>(poco => poco.Id);
// result: True
Console.WriteLine(result);
result = context.IsDatabaseGeneratedProperty<SimplePoco>(poco => poco.Name);
// result: False
Console.WriteLine(result);
}