有这样的方法吗?
object GetPrimaryKeyValue(DbEntityEntry entry);
或者应该如何实施?
答案 0 :(得分:30)
您需要将DbContext
转换为IObjectContextAdapter
,以便访问基础ObjectContext
,这样您就可以访问DbContext
隐藏的一些更高级的功能。
在您的类中导出DbContext
,以下方法将起作用。
object GetPrimaryKeyValue(DbEntityEntry entry)
{
var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity);
return objectStateEntry.EntityKey.EntityKeyValues[0].Value;
}
如果有多个密钥,则应迭代EntityKeyValues
属性。
答案 1 :(得分:0)
我也希望找到实体的主键。我在我的存储库中使用Generics,所以我不知道实体直到运行时。到目前为止,我发现这样做的唯一方法是使用sql语句。
public abstract class GenericRepository<T> : ApiController,IGenericRepository<T> where T : class
{
string sqlstr = @"
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + CONSTRAINT_NAME), 'IsPrimaryKey') = 1
AND TABLE_NAME = '" + typeof(T).ToString() + "' AND TABLE_SCHEMA = 'dbo'";
private Entities _entities = new Entities();
public virtual IQueryable<T> GetAll()
{
DbSqlQuery<T> queryTest = _entities.Set<T>().SqlQuery(sqlstr);
这只是全班的一部分,但希望能够展示我正在使用的解决方案。
答案 2 :(得分:0)
您不需要附加T item
。这可能是冗长的,但它确实有效。
public object[] GetPrimaryKeyValues<T>(DbContext databaseContext, T item)
{
return ((IObjectContextAdapter)databaseContext).ObjectContext.CreateEntityKey(typeof(T).Name.Pluralize(), item).EntityKeyValues.Select(kv => kv.Value).ToArray();
}
返回类型适合在Find
中使用。请注意,键值实际上是一个对象数组。
如果你需要Pluralize(),这里是:
using System;
using System.Data.Entity.Design.PluralizationServices;
using System.Linq;
using System.Reflection;
namespace Atlas.Core.Kernel.Extensions
{
public static class Strings
{
private static PluralizationService pluralizationService = PluralizationService.CreateService(System.Globalization.CultureInfo.CurrentUICulture);
public static string Pluralize(this MemberInfo memberInfo)//types, propertyinfos, ect
{
return Pluralize(memberInfo.Name.StripEnd());
}
public static string Pluralize(this string name)
{
return pluralizationService.Pluralize(name); // remove EF type suffix, if any
}
}
}
答案 3 :(得分:0)
我知道这有点旧,但我刚看到这个。
这是我是怎么做的(假设 pk 是 int)
public class Repository<T> : IDisposable, where T: class, new()
{
private int GetPrimaryKey(T item)
{
if (item == null)
return -1;
using (var db = new ApplicationContext())
{
ObjectSet<T> set = (db as IObjectContextAdapter).ObjectContext.CreateObjectSet<T>();
string keyName = set.EntitySet
.ElementType
.KeyMembers
.Select(x => x.Name)
.First();
Type type = typeof(T);
int val = int.Parse(type.GetProperty(keyName).GetValue(item).ToString());
return val;
}
}
}