Есть ли такой метод?
object GetPrimaryKeyValue(DbEntityEntry entry);
Или как это должно быть реализовано?
Есть ли такой метод?
object GetPrimaryKeyValue(DbEntityEntry entry);
Или как это должно быть реализовано?
Вам нужно отдать 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
.
Я также ищу, чтобы найти первичный ключ объекта. Я использую Generics в моем репозитории, поэтому я не знаю Entity до времени исполнения. Единственный способ, которым я нашел это до сих пор, - это сделать выражение 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);
Это просто оценка полного класса, но, надеюсь, показывает решение, которое я использую.
Вам не нужен прикрепленный 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
}
}
}