2016-11-01 7 views
0

C# rookie. Ниже мой код уже несколько часов пытается получить это, чтобы обновить некоторые поля в моей БД и попробовал много разных реализаций без везения.Динамический LINQ - Entity Framework 6 - Обновление записей для динамического выбора

 // Select all fields to update 
     using (var db = new Entities()) 
     { 
      // dbFields are trusted values 
      var query = db.tblRecords 
         .Where("id == " + f.id) 
         .Select("new(" + string.Join(",", dbFields.Keys) + ")"); 

      foreach (var item in query) 
      { 
       foreach (PropertyInfo property in query.ElementType.GetProperties()) 
       { 
        if (dbFields.ContainsKey(property.Name)) 
        { 
         // Set the value to view in debugger - should be dynamic cast eventually 
         var value = Convert.ToInt16(dbFields[property.Name]); 
         property.SetValue(item, value); 

         // Something like this throws error 'Object does not match target type' 
         // property.SetValue(query, item); 
        } 
       } 
      } 
      db.SaveChanges(); 
     } 

Приведенный выше код при выполнении не приводит к каким-либо изменениям в БД. Очевидно, что этот код нуждается в очистке, но я пытаюсь заставить базовые функции работать. Я верю, что мне может потребоваться, чтобы каким-то образом повторно применить «элемент» обратно в «запрос», но мне не повезло, что он работал независимо от того, какую реализацию я стараюсь, я всегда получаю «Объект не соответствует типу цели», ,

Эта полуполюсная проблема подтверждает это, но мне не очень понятно, так как я использую запрос Dynamic LINQ и не могу просто ссылаться на имена свойств напрямую. https://stackoverflow.com/a/25898203/3333134

+0

Зачем вам нужен этот 'Select (" новый ... 'Если? вы удаляете 'Select', у вас будут сущности из' tblRecords'. Изменение этих параметров приведет к изменениям, которые отслеживаются EF. –

ответ

1

Entity Framework будет выполнять обновления для вас на лицах, а не на пользовательских результатах. Ваш tblRecords содержит множество объектов, и это то, что вы хотите манипулировать, если вы хотите, чтобы Entity Framework помогла. Удалите проекцию (вызов Select), и запрос вернет объекты напрямую (слишком много столбцов, да, но мы расскажем об этом позже).

Динамическое обновление выполняется так же, как и любое другое динамическое назначение в C#, поскольку у вас есть нормальный объект для работы. Entity Framework будет отслеживать сделанные вами изменения и, вызывая SaveChanges, будет генерировать и выполнять соответствующие SQL-запросы.

Однако, если вы хотите оптимизировать и прекратить выбирать и создавать все значения в памяти, в первую очередь, даже те, которые не нужны, вы также можете выполнить обновление из памяти. Если вы создаете объект нужного типа самостоятельно и назначаете правильный идентификатор, вы можете использовать метод Attach(), чтобы добавить его в текущий контекст. С этого момента, все изменения будут записаны Entity Framework, а при вызове SaveChanges, все должно быть отправлено в базу данных:

// Select all fields to update 
using (var db = new Entities()) 
{ 
    // Assuming the entity contained in tblRecords is named "ObjRecord" 
    // Also assuming that the entity has a key named "id" 
    var objToUpdate = new ObjRecord { id = f.id }; 

    // Any changes made to the object so far won't be considered by EF 

    // Attach the object to the context 
    db.tblRecords.Attach(objToUpdate); 

    // EF now tracks the object, any new changes will be applied 

    foreach (PropertyInfo property in typeof(ObjRecord).GetProperties()) 
    { 
     if (dbFields.ContainsKey(property.Name)) 
     { 
      // Set the value to view in debugger - should be dynamic cast eventually 
      var value = Convert.ToInt16(dbFields[property.Name]); 
      property.SetValue(objToUpdate, value); 
     } 
    } 

    // Will only perform an UPDATE query, no SELECT at all 
    db.SaveChanges(); 
} 
+0

Работает и дает 1000 раз больше смысла за помощь тонну! Вместо db.Attach (objToUpdate) это верят он должен быть db.ObjRecord.Attach (objToUpdate). Еще раз спасибо! – user3333134

+0

@ user3333134 Абсолютно, мой плохой. Это то, что вы получаете, чтобы набрать его из памяти! –

0

Когда вы делаете SELECT NEW ..., он выбирает только определенные поля и не будет отслеживать обновления для вас. Я думаю, что если вы измените запрос, чтобы быть это будет работать:

var query = db.tblRecords.Where(x=>x.id == id); 
Смежные вопросы