对于我的数据库中的一些属性,我需要手动计算它们的Id #,所以对于这些属性,我在OnModelCreating
中执行.Property(p => p.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);
然后,在存储库中,我有一个方法可以计算出给定类型的Id。我更希望系统智能化,并检查DatabaseGeneratedOption.None
或DatabaseGeneratedOption.Identity
是否返回下一个Id或0。
如何检查(从存储库内部)给定类型(T)的DatabaseGeneratedOption
是什么?
发布于 2016-03-23 08:32:36
多亏了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;
}
发布于 2016-03-24 05:51:52
正如我在评论中所说的,您的解决方案是通过从EntityType
返回CLR类型名称的代码优先存储模型来工作的。但是,数据库优先的商店模型会返回商店名称。这些名称不一定与CLR类型名称匹配。
要使此方法独立于EF的存储模型,我们需要访问存储- CLR映射空间(CSSpace
),找到EntitySet
(通过CLR名称),并将其KeyMembers
与存储模型(Property.Column
)中的列进行匹配,因为这些列包含正确的IsStoreGeneratedIdentity
值。(CLR属性也具有此属性,但它始终为false)。
所以这就是我们得到的(作为一个封装在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);
}
https://stackoverflow.com/questions/36163841
复制相似问题