2013-08-27 5 views
0
public void ApproveRowTable(string tablename, List<int> idValues) 
{ 
    foreach (var x in idValues) 
    { 
      var context = new SSPModel.sspEntities(); 
      var genRules = (from a in context.GeneralRules 
          where a.ID == x 
          select a).SingleOrDefault(); 
      genRules.Approved_by = GlobalClass.GlobalVar; 
      genRules.Approved_on = DateTime.Now; 
      context.SaveChanges(); 
    } 
} 

В моем запросе (from a in context.GeneralRules ...) Я хотел бы сделать это базовый запрос по параметру (TABLENAME), а не я должен пойти и поставить имя таблицы в запрос (как это делается прямо сейчас). В любом случае я могу заставить его это сделать .. basic .. from a in context.TABLENAME -- TABLENAME - это параметр, который будет передан при вызове функции. СправкаLinq в объект - динамический запрос

+2

У всех ваших объектов есть свойства 'ID',' Approved_by' и 'Approved_on'? Если да, наследуют ли они от базового абстрактного класса эти свойства? –

+0

С динамическим запросом вы подразумеваете «Динамический LINQ» в качестве имени библиотеки или «Я бы хотел, чтобы мой запрос был динамическим»? – xanatos

+0

Возможно, вы думаете «общий запрос»? Вы хотите использовать этот метод для разных типов (EF objects = tables)? –

ответ

0

Предполагаю, что вы хотели бы иметь общий метод. Когда вы используете EF, все ваши таблицы представлены как объекты, поэтому вам не нужно указывать, какую таблицу вы хотите по имени, просто используйте общий параметр.

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

public void ApproveRowTable<T>(List<int> idValues) 
{ 
    var context = new SSPModel.sspEntities(); 
    var table = context.GetType().GetProperties().OfType<T>().Single(); 
    var genRules = (from a in table 
          where a.ID == x 
          select a).SingleOrDefault(); 
      genRules.Approved_by = GlobalClass.GlobalVar; 
      genRules.Approved_on = DateTime.Now; 
      context.SaveChanges(); 
} 
+0

И этот метод является общедоступным для других разработчиков, вам нужно «попытаться поймать» часть отражения, потому что кто-то может использовать метод с неправильным параметром типа, и это приведет к исключению. –

+0

Я все еще хотел бы искать по имени .. помог бы мне больше –

+0

Я пробовал, но я не могу найти способ. Существует проблема, потому что если вы хотите получить доступ к столбцам таблицы (свойства объекта EF), вы должны сначала знать ее тип. Вы можете сделать это, передав параметр типа, но затем мы снова находимся в ситуации, когда generics - лучшее решение. –

1

Это будет сложно, если типы объектов не будут реализовывать один и тот же интерфейс или получить один и тот же класс. Если они делают, это довольно просто:

// example base type, which your entities would need to implement 
public interface IApprovable 
{ 
    public int ID {get; set;} 
    public string Approved_by {get; set;} 
    public DateTime Approved_on {get; set;} 
} 
//... 
public void ApproveRowTable<T>(List<int> idValues) 
    where T : IApprovable 
{ 
    using(var context = new SSPModel.sspEntities()) 
    { 
     var table = context.Set<T>(); 
     var entities = table.Where(e => idValues.Contains(e.ID)); 
     foreach(var entity in entities) 
     { 
      entity.Approved_by = GlobalClass.GlobalVar; 
      entity.Approved_on = DateTime.Now; 
     } 
     context.SaveChanges(); 
    } 
} 

Если типы сущностей не реализуют общий базовый тип, то вы должны изменить их, создавая пустые партиалы у которых его реализации:

public partial class GeneralRule : IApprovable {} 

Если вы не может этого сделать, тогда вы можете сделать что-то вроде следующего. (Я предполагаю, что ID является ПК, так что мы можем использовать Find() вместо необходимости создания выражения:

public void ApproveTableRows(Type entityType, IEnumerable<int> idsToApprove) 
{ 
    using(var context = new SSPModel.sspEntities()) 
    { 
     var set = context.Set(entityType); 
     if(set == null) 
      throw new ArgumentException("No DbSet found with provided name", "tableSetName"); 

     var approveByProperty = entityType.GetProperty("Approved_by"); 
     var approveOnProperty = entityType.GetProperty("Approved_on"); 
     if(approveByProperty == null || approveOnProperty == null) 
      throw new InvalidOperationException("Entity type does not contain approval properties"); 

     foreach (object id in idsToApprove) 
     { 
      var entityInstance = set.Find(id); 
      approveByProperty.SetValue(entityInstance, GlobalClass.GlobalVar); 
      approveOnProperty.SetValue(entityInstance, DateTime.Now); 
     } 

     context.SaveChanges(); 
    } 
} 

Как вы можете видеть, это менее эффективно, так как он выдает новый запрос для каждого идентификатора, а чем получение их всех одновременно. Кроме того, метод принимает объект Type, а не строку, чтобы избежать необходимости выслеживать правильное свойство путем отражения. Это может быть улучшено, но на самом деле я думаю, что вам, вероятно, следует обновить свои сущности для реализации общий интерфейс.

Смежные вопросы