如何获取ObjectSet 的实体密钥名称?
我在我的通用存储库中创建了一个通用的ObjectSet
。
我想得到的是ObjectSet
的EntityKey的name
,以便我可以在DataContext.GetObjectByKey
使用它。
我已经四处搜索并深入挖掘,但我似乎无法在ObjectSet
类中的任何位置找到此值。
我刚才看到了一个很好的方法来做到这一点并没有找到一个。 我通常最终在某处和其中构建一个GetEntityByKey扩展方法,连接字符串以构建TryGetObjectByKey调用的实体密钥。 构建实体键的一般想法是这样的:
internal class Program { private static void Main(string[] args) { var dc = new AdventureWorksLT2008Entities(); object c; dc.TryGetObjectByKey(GetEntityKey(dc.Customers, 23), out c); var customer = c as Customer; Console.WriteLine(customer.EmailAddress); } private static EntityKey GetEntityKey(ObjectSet objectSet, object keyValue) where T : class { var entitySetName = objectSet.Context.DefaultContainerName + "." + objectSet.EntitySet.Name; var keyPropertyName = objectSet.EntitySet.ElementType.KeyMembers[0].ToString(); var entityKey = new EntityKey(entitySetName, new[] {new EntityKeyMember(keyPropertyName, keyValue)}); return entityKey; } }
你也许可以做类似的事情。 为简单起见,此示例假定每个EntityKey使用一个字段 – 对于多个值键,您需要使用ObjectSet
执行稍微复杂的操作,并将所有键传递到EntityKey构造函数中。
通用:
public class GenericoRepositorio : IGenericoRepositorio where T : class { protected readonly ObjectSet ObjetoSet; protected readonly ModeloContainer Contexto; public GenericoRepositorio(ModeloContainer contexto) { Contexto = contexto; ObjetoSet = Contexto.CreateObjectSet (); } public T Carregar(int id) { object objeto; Contexto.TryGetObjectByKey(GetEntityKey(ObjetoSet, id), out objeto); return (T)objeto; } private static EntityKey GetEntityKey (ObjectSet objectSet, object keyValue) where T : class { var entitySetName = objectSet.Context.DefaultContainerName + "." + objectSet.EntitySet.Name; var keyPropertyName = objectSet.EntitySet.ElementType.KeyMembers[0].ToString(); var entityKey = new EntityKey(entitySetName, new[] { new EntityKeyMember(keyPropertyName, keyValue) }); return entityKey; } }
查看我关于获取EntitySetName的post 。 对于我的存储库,我创建了一个属性,该属性获取特定类名的实体集名称,以完成您要执行的操作。
这应该为您提供ObjectSet的所有通用参数(类型):
objectSet.GetType().GetGenericArguments().First()
我很难尝试做几乎相同的事情,在类型未知时在运行时获取主键名称和值。 我只是试图实现删除审计方案,我发现的每个解决方案都涉及多余的代码,我真的不明白。 DbContext不提供EntityKey,这也令人困惑和恼人。 最后5行可以为您节省5小时和1年的秃头。 我没有尝试插入,所以如果你这样做,你需要仔细检查这些值,因为它们可能是0或null。
foreach(var entry in ChangeTracker.Entries()) { ... case EntityState.Deleted: var oc = ((IObjectContextAdapter)this).ObjectContext; //this is a DbContext EntityKey ek = oc.ObjectStateManager.GetObjectStateEntry(entry.Entity).EntityKey; var tablename = ek.EntitySetName; var primaryKeyField = ek.EntityKeyValues[0].Key; //assumes only 1 primary key var primaryKeyValue = ek.EntityKeyValues[0].Value;
var objContext = ((IObjectContextAdapter)this.context).ObjectContext;
var objSet = objContext.CreateObjectSet
var entityKey = objContext.CreateEntityKey(objSet.EntitySet.Name, entityToUpdate);
Object foundEntity;
var exits = objContext.TryGetObjectByKey(entityKey, out foundEntity);
if (exits && this.dbset.Local != null && this.dbset.Local.Contains(foundEntity) &&this.dbset.Local.Any()) { if (entityKey.EntityKeyValues != null && entityKey.EntityKeyValues.Any()) { DbEntityEntry entry = this.context.Entry(this.dbset.Find(entityKey.EntityKeyValues.FirstOrDefault().Value)); entry.CurrentValues.SetValues(entityToUpdate); } } this.context.SaveChanges();
用EF 6测试。
它将为给定的DbEntityEntry的每个主键值返回一个对象数组。
他们可能是边缘情况,这不起作用 – 但对我的简单需求很有效。
希望这有助于其他人。
object[] GetPrimaryKeyValue(DbEntityEntry entry) { List