我在这里看到的答案是针对ObjectContext的。使用DbContext时是否有确定实体主键名称的属性?
啊..其中一个我希望实体框架是开源的!我可以从.Find方法收集这个主键名称信息: - )
答案 0 :(得分:26)
你不能使用DbContext
- DbContext API只是愚蠢的包装器,只有最需要的功能。对于更复杂的内容,您必须将DbContext
转换回ObjectContext
并使用它。尝试这样的事情:
提取键名:
public static string[] GetEntityKeyNames<TEntity>(this DbContext context) where TEntity : class
{
if (context == null)
throw new ArgumentNullException("context");
var set = ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet<TEntity>();
var entitySet = set.EntitySet;
return entitySet.ElementType.KeyMembers.Select(k => k.Name).ToArray();
}
这是一种提取实体的键值的方法:
public static IEnumerable<object> GetEntityKeys<TEntity>(this DbContext context, TEntity entity)
where TEntity : class
{
if (context == null)
throw new NullReferenceException("context");
var type = typeof(TEntity);
var set = ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet<TEntity>();
var entitySet = set.EntitySet;
var keys = entitySet.ElementType.KeyMembers;
var props = keys.Select(k => type.GetProperty(k.Name));
return props.Select(p => p.GetValue(entity));
}
答案 1 :(得分:4)
solution proposed by Ladislav Mrnka不会将衍生实体作为You can't create an object set for a derived type。您会看到此错误:
ArgumentException:没有为指定定义的EntitySets 实体类型...如果...是派生类型,请使用 基类型代替。参数名称:TEntity
这是我避免创建对象集的解决方案:
public string[] GetEntityKeyNames<TEntity>(DbContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
var objectContext = ((IObjectContextAdapter)Context).ObjectContext;
//We must use the namespace of the context and the type name of the entity
string entityTypeName = context.GetType().Namespace + '.' + typeof(TEntity).Name;
var entityType = objectContext.MetadataWorkspace.GetItem<EntityType>(entityTypeName, DataSpace.CSpace);
return entityType.KeyProperties.Select(k => k.Name).ToArray();
}
答案 2 :(得分:1)
你可以访问ObjectContext,因为DbContext主要包装ObjectContext ...
见
http://msdn.microsoft.com/en-us/library/gg696590%28v=vs.103%29.aspx
http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext%28v=vs.103%29.aspx
http://msdn.microsoft.com/en-us/library/dd283139.aspx
答案 3 :(得分:1)
您可以从EntityKey类(http://msdn.microsoft.com/en-us/library/system.data.entitykey.aspx)中找到主键值。
你可以从DbContext中找到EntityKey对象,如下所示:
ObjectContext context = ((IObjectContextAdapter)dbContext).ObjectContext;
EntityKey key = context.ObjectStateManager.GetObjectStateEntry(model).EntityKey;
答案 4 :(得分:1)
这是我做的,以确保我得到了钥匙。它与@Agus Syahputra的答案基本相同,但有一个重要区别。我在下面添加了完整的答案。
注意:我只在EF6上测试了这个,我不确定这是否适用于早期版本的EF。
//I'm currently inside savechanges of my dbcontext
//if you're typing this code outside your dbcontext, replace this with your dbcontext
var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity);
string keyName = objectStateEntry.EntityKey.EntityKeyValues[0].Key;