универсальный метод для поиска объекта LINQ на основе его типа

#linq #generics

#linq #общие

Вопрос:

 partial void UpdateDenomLimit(DenomLimit instance)
{
     var oldData = DataClassesDataContext.DenomLimits.Where(b => b.ID == instance.ID).First();

     //Code that logs the audit when instance and oldData is passed to it
     LogAudit(oldData, instance);

     //Code that updates the instance
     this.ExecuteDynamicUpdate(instance);
}
  

Выше приведен метод обновления экземпляра DenomLimit в базе данных.
Я регистрирую аудит того, какие изменения внесены в объект. Для этого я получаю предыдущее состояние экземпляра с помощью следующего кода, и он работает нормально:

      var oldData = DataClassesDataContext.DenomLimits.Where(b => b.ID == instance.ID).First();
  

теперь мне нужен общий запрос LINQ, который может извлекать старые данные, когда ему передаются три параметра:
1. экземпляр любого типа
2. Имя столбца первичного ключа
3. Значение столбца первичного ключа для переданного экземпляра.

…так что я могу сохранить этот код в LogAudit, а затем не нужно извлекать в каждой функции.

Запрос LINQ, который, возможно, будет выглядеть:

 var oldData = DataClassesDataContext.GetTable<instance>().Where("b => b."   colName   " == @0", new object[] { id }).First();
  

Ответ №1:

Полное пространство имен используется здесь для указания пространства имен, из которого оно было получено, чтобы упростить его включение в ваш код.

     public T GetFirstOrDefault<T>(System.Linq.Expressions.Expression<Func<T, bool>> func) where T : class
    {
        DataClassesDataContext.ObjectContext.CreateObjectSet<T>().FirstOrDefault(func);
        // For EF 4.1 Code First
        //return (ctx as System.Data.Entity.Infrastructure.IObjectContextAdapter).ObjectContext.CreateObjectSet<T>().FirstOrDefault(func);
        // or
        //return ctx.Set<T>().FirstOrDefault(func);
    }
  

В этом случае использование выражения функции позволяет EF определить, какие данные вы ищете.
Вот пример того, как он будет использоваться:

 var a1 = GetFirstOrDefault<DenomLimits>(p => p.ID == oldData.ID);
var a2 = GetFirstOrDefault<DenomLimits>(p => p.OtherID == 5);