2008-12-22 13 views
6

Opublikowałem ten question wczoraj wieczorem, co doprowadziło mnie do odkrycia problemu ogromnego!Linq-to-Sql SubmitChanges nie aktualizuje pól ... dlaczego?

Mam kolumnę dziesiętną w mojej bazie danych o nazwie Jednostki, w dowolnym momencie ustawiam wartość kolumny na NON ZERO, a SubmitChanges aktualizuje kolumnę z nową wartością. Jeśli próbuję ustawić wartość kolumny na ZERO, zmiany właściwości SubmitChanges nie aktualizują kolumny.

data.Units = this.ReadProperty<decimal>(UnitsProperty); 
data.UnitPrice = this.ReadProperty<decimal>(UnitPriceProperty); 
data.Price = this.ReadProperty<decimal>(PriceProperty); 

Wziąłem okiem na log DataContext i widzę, że pole z wartością zero nie jest uwzględnione w zapytaniu. Nawet jeśli spróbuję zmienić kod Linq, Linq go ignoruje.

data.Units = 0; 
data.UnitPrice = 0; 
data.Price = 0; 

Nie trzeba dodawać, że to mnie zabija! Jakieś pomysły, dlaczego tak się dzieje?

Rozwiązanie

zorientowali się mój problem z pomocą Wspólnoty, tak. Mój problem powodowany był faktem, kiedy stworzyłem mój obiekt do dołączenia, domyślna wartość kolumny została ustawiona na zero, więc gdy próbowałem przypisać wartość do zera ... LinqToSql mówi hej ... nic się nie zmieniło, więc Nie aktualizuję wartości.

Co robię teraz ... po prostu sprawiają, że praca jest następujący:

ctx.DataContext.InvoiceItems.Attach(data, true); 

To wydaje się zmusić wszystkie wartości napisać się do bazy danych. To działa na razie.

+0

Którykolwiek z metod częściowych na twojej klasie, takich jak OnCreated() lub OnChanged() powoduje zakłócenia? Czy potrójnie sprawdziłeś swój model? –

+0

@Dave Głupie pytanie ... ale co masz na myśli, mówiąc potrójnie gut-check? – mattruma

+0

Mam na myśli, że jest wcześnie i jeszcze nie miałem kawy. ;-) Mam na myśli to, czy dwukrotnie sprawdziłeś definicję pliku dbml (typy danych, zerowalne, relacje) z bazą danych? –

Odpowiedz

2

Znalazłem swój problem z pomocą społeczności SO. Mój problem powodowany był faktem, kiedy stworzyłem mój obiekt do dołączenia, domyślna wartość kolumny została ustawiona na zero, więc gdy próbowałem przypisać wartość do zera ... LinqToSql mówi hej ... nic się nie zmieniło, więc Nie aktualizuję wartości.

Co teraz robię ...tylko, że praca jest następujący:

ctx.DataContext.InvoiceItems.Attach(data, true); 

To wydaje się zmusić wszystkie wartości napisać się do bazy danych. To działa na razie.

3

Próbowałem odtworzyć to z następującego kodu, ale dla mnie to działa.

using (DataClasses1DataContext ctx = new DataClasses1DataContext()) 
{ 
    var obj = ctx.DecimalColumnTables.First(); 
    Debug.Assert(obj.B != 0); 
    obj.B = 0; 
    ctx.SubmitChanges(); 
} 

Sądzę, że musi istnieć coś wyjątkowego w twojej domenie, które to powoduje. Proponuję stworzyć takie proste repro z modelem swojej domeny i zobaczyć, co się stanie.

LINQ do SQL ignoruje aktualizacje bieżącej wartości, więc jeśli pole było już zerowe, może nie być żadnych aktualizacji.

Wyłącz: OR/M, którego używasz to LINQ do SQL. LINQ to nazwa funkcji zapytania w .NET, ale LINQ nie definiuje ani nie implementuje żadnej logiki aktualizacji. Problem dotyczy LINQ do SQL, a nie LINQ.

+0

Dzięki! Sprawdzę to! – mattruma

+0

Masz rację na @Gaspar Nagy ... Linq to Sql ignorował zmianę. – mattruma

2

Oczywiste pytanie, ale czy na pewno kolumna jest zamapowana w pliku dbml/mapping?

Również - czy jest to kolumna obliczeniowa? (tj. cena = > jednostek * jednostka ceny)

2

Niektóre więcej informacji ... I zorientowali się mój problem ... To raczej brak zrozumienia LinqToSql ... gdzie robie:

private void Child_Update(Invoice parent) 
{ 
     using (var ctx = Csla.Data.ContextManager 
      .GetManager(Database.ApplicationConnection, false)) 
     { 
      var data = new Gimli.Data.InvoiceItem() 
      { 
       InvoiceItemId = ReadProperty(InvoiceItemIdProperty) 
      }; 

      ctx.DataContext.InvoiceItems.Attach(data); 

      if (this.IsSelfDirty) 
      { 
       // Update properties 
      } 
    } 
} 

myślałem, że to byłoby załadować pierwotne wartości ... chodzi o to, że tworzy nowy obiekt z wartościami domyślnymi ... puste wartości, np. 0 dla dziesiętnych, Guid.Empty dla uniqueidentifiers i tak dalej.

Kiedy więc aktualizuje właściwości, widzi Jednostki już jako 0 i ustawia je na zero. Cóż, LinqToSql nie rozpoznaje tego jako zmiany, więc nie aktualizuje daty pola. Więc co miałem zrobić, jest następujący:

ctx.DataContext.InvoiceItems.Attach(data, true); 

Teraz wszystkie modyfikacje są generowane w rachunku aktualizacji czy istnieje naprawdę zmiana albo nie. To działa ... wydaje się nieco hackish!

0

Miałem ten problem i wszystkie sugestie, które widziałem, nie dotyczyły ani nie działały.

Ale odkryłem, że popełniłem bardzo prosty błąd!

Podczas aktualizacji właściwości faktycznie wywoływałem niestandardową metodę Set (ponieważ były inne rzeczy, które wymagały zmiany w odpowiedzi na główną właściwość, o której mowa).

Po godzinach drapania głowy zauważyłem, że moja metoda Set aktualizuje element prywatny, a nie właściwość publiczną, tj. This._Walking = value;

Wszystko, co musiałem zrobić, to zmienić to na WALKING = wartość; i wszystko zaczęło działać!

1

Prawidłowa odpowiedź jest aż wskazał użyć specjalnego przeciążenie Attach która przyjmuje parametr logiczną rozważyć go jako modyfikowane (popełnia błąd za pomocą innego przeciążenie i to po prostu nie będzie działać):

ctx.DataContext.InvoiceItems.Attach(data, true); 

Należy jednak zauważyć, że w tabeli typu "znacznik czasu" może być wciąż wymagana kolumna "Wersja".