2016-11-01 3 views
0

C# 신참. 아래 코드는 내 DB의 일부 필드를 업데이트하기 위해 몇 시간 씩 노력해 왔으며 행운없이 많은 구현을 시도했습니다.동적 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(); 
     } 

위의 코드를 실행해도 DB가 변경되지 않습니다. 분명히이 코드는 약간의 정리가 필요하지만 기본 기능을 작동 시키려고합니다. 내가해야 할 수도 있습니다 어떻게 든 '쿼리'로 다시 '항목'을 다시 적용하는 것입니다하지만 난 행운을 얻으려고 아무리 노력하고있어 내가 노력하고있어 난 항상 '대상이 일치하지 않는 대상 유형' .

이 비슷한 문제는 내가 동적 LINQ 쿼리를 사용하고 있으며 속성 이름을 직접 참조 할 수 없기 때문에 나에게 분명하지 않지만 다시 확인됩니다. https://stackoverflow.com/a/25898203/3333134

+0

당신이 필요로하는이 '선택 이유는 무엇입니까 ("새 ...'있다면? 당신은'tblRecords'에서 엔티티를 가질'선택 '을 제거합니다. 변경하면 EF가 추적하는 변경 사항이 발생합니다. –

답변

1

Entity Framework는 사용자 정의 결과가 아닌 엔티티에서 업데이트를 수행합니다. tblRecords은 많은 엔티티를 보유하고 있으며, 이는 Entity Framework가 도움이되기를 원하는 경우 조작하려는 것입니다. 투영 (Select에 대한 호출)을 제거하면 쿼리가 개체를 직접 반환합니다 (열이 너무 많으면, 그렇지만 나중에 다루 겠습니다).

동적 업데이트는 정상적인 개체를 가지고 있기 때문에 C#의 다른 동적 할당과 동일한 방식으로 수행됩니다. Entity Framework는 변경 내용을 추적하고 SaveChanges을 호출하면 해당 SQL 쿼리를 생성하고 실행합니다. 그러나

, 최적화하고 처음에 메모리에 모든 값을 선택하고 생성을 중지, 심지어 필요하지 않은 것들, 당신은 또한 메모리에서 업데이트를 수행 할 수 있습니다하려는 경우. 자신이 올바른 유형의 객체를 만들고 올바른 ID를 할당하면 Attach() 메서드를 사용하여 현재 ID를 해당 컨텍스트에 추가 할 수 있습니다. 그 시점에서, 변경 사항은 엔티티 프레임 워크에 의해 기록 될 것입니다, 당신은 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

db.Attach (objToUpdate) 대신 1 톤 도움을주었습니다. 그것은 db.ObjRecord.Attach (objToUpdate) 여야합니다. 다시 고마워요 – user3333134

+0

@ user3333134 물론, 내 잘못입니다. 그게 당신이 그것을 메모리에서 타이핑 할 때 얻는 것입니다! –

0

SELECT NEW ...을 입력하면 특정 필드 만 선택되고 업데이트가 추적되지 않습니다. 쿼리를 변경하면 작동 할 것입니다.

var query = db.tblRecords.Where(x=>x.id == id);