首先在代码中获取任意实体的主键值
有这样的方法吗?
object GetPrimaryKeyValue(DbEntityEntry entry);
或者应该如何实施?
您需要将DbContext
为IObjectContextAdapter
以便可以访问底层的ObjectContext
,这样您就可以访问DbContext
隐藏的一些更高级的function。
在您的类中导出DbContext
,以下方法将起作用。
object GetPrimaryKeyValue(DbEntityEntry entry) { var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity); return objectStateEntry.EntityKey.EntityKeyValues[0].Value; }
如果有多个键,则应迭代EntityKeyValues
属性。
我也希望找到一个实体的主键。 我在我的存储库中使用Generics,所以直到运行时我才知道实体。 到目前为止,我发现这样做的唯一方法是使用sql语句。
public abstract class GenericRepository : ApiController,IGenericRepository 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 GetAll() { DbSqlQuery queryTest = _entities.Set ().SqlQuery(sqlstr);
这只是全class的一部分,但希望能够展示我正在使用的解决方案。
您不需要附加的T item
。 这可能是冗长的,但它的确有效。
public object[] GetPrimaryKeyValues(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 } } }