2010-06-10 3 views
7

linq를 SQL 엔티티로 업데이트하는 데 문제가 있습니다. 어떤 이유로 든 item 엔티티의 모든 필드를 이름 외에도 업데이트 할 수 있습니다.Linq to SQL - 업데이트 실패

여기에 내가 쓴 두 개의 간단한 테스트는 다음과 같습니다

[TestMethod] 
     public void TestUpdateName() { 
      using (var context = new SimoneDataContext()) { 
       Item item = context.Items.First(); 

       if (item != null) { 
        item.Name = "My New Name"; 
        context.SubmitChanges(); 
       } 
      } 
     } 

     [TestMethod] 
     public void TestUpdateMPN() { 
      using (var context = new SimoneDataContext()) { 
       Item item = context.Items.First(); 

       if (item != null) { 
        item.MPN = "My New MPN"; 
        context.SubmitChanges(); 
       } 
      } 
     } 

불행하게도, TestUpdateName()는 다음과 같은 오류와 함께 실패합니다 System.Data.SqlClient.SqlException: Incorrect syntax near the keyword 'WHERE'..

을 그리고 여기에 출력 된 SQL의 :

UPDATE [dbo].[Items] SET WHERE ([Id] = @p0) AND ([CategoryId] = @p1) AND ([MPN] = @p2) AND ([Height] = @p3) AND ([Width] = @p4) AND ([Weight] = @p5) AND ([Length] = @p6) AND ([AdministrativeCost] = @p7) -- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- @p2: Input VarChar (Size = 10; Prec = 0; Scale = 0) [My New MPN] -- @p3: Input Decimal (Size = 0; Prec = 5; Scale = 3) [30.000] -- @p4: Input Decimal (Size = 0; Prec = 5; Scale = 3) [10.000] -- @p5: Input Decimal (Size = 0; Prec = 5; Scale = 3) [40.000] -- @p6: Input Decimal (Size = 0; Prec = 5; Scale = 3) [30.000] -- @p7: Input Money (Size = 0; Prec = 19; Scale = 4) [350.0000] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.4926

로 당신은 볼 수 있습니다, 업데이트가 생성되지 않습니다 (SET는 비어 있습니다 ...) 나는 이런 일이 일어나는 이유를 전혀 모른다.

이미 ... 예, 테이블 Item에는 PK (Id)가 있습니다. 고맙습니다.!

업데이트 : 오류는 GetHashcode()를 재정 의하여 발생합니다. 이 내 현재의 구현 :

return string.Format("{0}|{1}|{2}|{3}", Name, Id, UPC, AdministrativeCost).GetHashCode();

+0

당신이 이름과 다른 하나 개의 속성을 수정하면 어떻게되는지? 둘 다 또는 다른 속성 만 업데이트합니까? 또한 생성 된 코드에서 Name의 setter는'PropertyChanged' 이벤트를 발생 시키는가? DataContext는 이벤트가 발생하지 않는 한 변경 사항을 고려하지 않습니다. –

+0

이름과 다른 속성을 수정하면 다른 속성 만 변경됩니다. –

답변

12

DBML이 동기화되지 않은 것처럼 들립니다. 테이블을 삭제하고 다시 추가하고 다시 실행해야합니다.

Items 테이블을 수동으로 삭제하고 다시 추가하기 만하면됩니다.

수정 : 편집 내용에 따라 GetHashCode에 관한 다음 스레드를 확인해야합니다.

http://social.msdn.microsoft.com/forums/en-US/linqtosql/thread/6cc6c226-f718-4b22-baad-dba709afe74b/

.Net rules claim that GetHashCode() and Equals() must always be implemented in tandem. Two objects that are equal must have the same hash code.

Also, the combination of GetHashCode() + Equals() forms the entity's concept of identity. If you make it based on field values (other than PK) then the identity changes as you change the fields. This is bad if L2S must lookup other info in a dictionary based on the entity's identity, and especially if L2S needs to find an entity in its identity cache!

Advice: don't change the identity of an entity. L2S expects it to be based on the object's natural (address based) identity.

+0

테이블을 수동으로 삭제하면 작동하지 않습니다. 또한 Hugati 도구를 사용하여 다시 동기화하려고 시도했지만 동일한 오류가 발생합니다. –

+0

@Isaac'TestUpdateMPN'이 작동하고'TestUpdateName' 만 실패합니까? 이 오류는 테이블의 dbml 정의가 스키마와 일치하지 않을 때 발생하는 것으로 보입니다. – Kelsey

+0

+1에 대한 GetHashCode() 물건. 그게 내 문제 였어. GetHashCode()가 사용하는 필드를 변경하려고하면 무시됩니다. – tandrewnichols

0

SQL이 SET 절 (SET 후 더 [Name] = @pXX이 없음을 통지)의 내용이 포함되지 생성되는 것으로 보인다. 엔터티 필드의 모든 속성 (데이터 형식, 크기 등)이 dbml 디자이너에서 올바르게 설정 되었습니까?

+0

나는 그것에주의를 기울였다. 그리고 나는 1 분 전에 그 지위를 편집했다. DBML의 속성이 올바른 것처럼 보입니다. Hugati DBML 도구를 사용하여 데이터베이스와 동기화 된 DBML 스키마를 유지 관리합니다. 답장을 보내 주셔서 감사합니다. –

+0

@Isaac : 최신 버전은 여전히이 문제를 반영합니다 ('UPDATE [dbo]. [Items] SET WHERE ...'). L2S는 업데이트 할 열의 목록과 함께가는 값을 생성하지 않습니다 (UPDATE [dbo]. [항목] SET [이름] = @ p0 WHERE ... 또는 이와 유사한 내용). –