EntityFramework - 检测DatabaseGenerated属性

时间:2013-08-14 07:21:50

标签: c#

我正在使用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在模型或代码优先模型中标记属性。数据库本身并不重要,就像实体框架背后的哲学一样。

1 个答案:

答案 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);
}