实体框架 - 确定给定类型的HasDatabaseGeneratedOption设置

时间:2016-03-22 19:48:58

标签: c# entity-framework reflection

对于我的数据库中的某些属性,我需要手动计算其ID#,因此对于这些属性,我在.Property(p => p.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);OnModelCreating

然后,在存储库中我有一个方法来计算给定类型的Id。我希望系统具有智能性,并检查DatabaseGeneratedOption.NoneDatabaseGeneratedOption.Identity是否返回下一个Id或0。

如何检查(从存储库中)给定类型(T)的DatabaseGeneratedOption是什么?

2 个答案:

答案 0 :(得分:0)

感谢George的评论,我能够提出这个解决方案:

bool? _sqlGeneratesID;
bool IRepository<TEntity>.IsStoreGeneratedIdentity()
{
    if (!_sqlGeneratesID.HasValue)
    {
        var items = (_context as IObjectContextAdapter)?.ObjectContext.MetadataWorkspace.GetItems(DataSpace.SSpace).OfType<EntityType>();
        var entity = items.Single(x => x.Name == typeof(TEntity).Name);
        _sqlGeneratesID = entity.KeyProperties.FirstOrDefault()?.IsStoreGeneratedIdentity ?? false;
    }

    return _sqlGeneratesID.Value;
}

答案 1 :(得分:0)

正如我在评论中所说,您的解决方案依赖于代码优先存储模型,从EntityType返回CLR类型名称。但是,数据库优先存储模型返回商店名称。这些名称不一定与CLR类型名称匹配。

要使此方法独立于EF的商店模型,我们需要访问store-CLR映射空间(CSSpace)并找到EntitySet(按CLR名称)并匹配其KeyMembers包含商店模型中的列(Property.Column),因为这些列包含正确的IsStoreGeneratedIdentity值。 (CLR属性也有此属性,但它总是错误的。)

所以这就是我们得到的(作为封装在DbContext子类型中的方法):

public bool IsStoreGeneratedIdentity<TEntity>()
{
    var entityContainerMappings = (this as IObjectContextAdapter).ObjectContext
        .MetadataWorkspace.GetItems(DataSpace.CSSpace)
        .OfType<EntityContainerMapping>();

    var entityTypeMappings = entityContainerMappings
        .SelectMany(m => m.EntitySetMappings
            .Where(esm => esm.EntitySet.ElementType.Name == typeof(TEntity).Name))
        .SelectMany(esm => esm.EntityTypeMappings).ToArray();

    var keyMappings = (from km in entityTypeMappings.SelectMany(etm => etm.EntityType.KeyMembers)
        join pm in entityTypeMappings.SelectMany(etm => etm.Fragments)
            .SelectMany(mf => mf.PropertyMappings)
            .OfType<ScalarPropertyMapping>()
            on km.Name equals pm.Property.Name
        select pm
        );

    return keyMappings.Any(pm => pm.Column.IsStoreGeneratedIdentity);
}