2008-12-22 35 views
6

Tôi đã đăng số question tối hôm qua, điều này đã khiến tôi khám phá ra một sự cố lớn!Linq-to-Sql SubmitChanges không cập nhật các trường ... tại sao?

Tôi có một cột thập phân trong cơ sở dữ liệu của tôi được gọi là Đơn vị, bất kỳ lúc nào tôi đặt giá trị của cột thành KHÔNG CÓ, và GửiChỉnh sửa cột cập nhật với giá trị mới. Nếu tôi cố gắng đặt giá trị của cột thành ZERO, SubmitChanges không cập nhật cột.

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

Tôi đã lấy một cái nhìn tại các log DataContext và tôi có thể thấy rằng trường với giá trị ZERO không được bao gồm trong truy vấn. Ngay cả khi tôi cố gắng mã cứng thay đổi, Linq bỏ qua nó.

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

Không cần phải nói điều này đang giết chết tôi! Bất kỳ ý tưởng tại sao điều này xảy ra?

Giải pháp

tôi đã tìm ra vấn đề của tôi với sự giúp đỡ của cộng đồng SO. Vấn đề của tôi đã được gây ra bởi thực tế khi tôi tạo ra thực thể của tôi để đính kèm, giá trị mặc định của cột được thiết lập để không, do đó, khi nó đã cố gắng để gán giá trị cho số không ... LinqToSql nói hey ... không có gì thay đổi, vì vậy Tôi không cập nhật giá trị.

Những gì tôi đang làm gì bây giờ ... chỉ để làm cho nó làm việc như sau:

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

Đó dường như để buộc tất cả các giá trị để viết bản thân cơ sở dữ liệu. Điều này làm việc cho bây giờ.

+0

Có bất kỳ phương pháp một phần nào trong lớp của bạn như OnCreated() hoặc OnChanged() gây nhiễu sóng không? Bạn đã kiểm tra ba lần mô hình của mình chưa? –

+0

@Dave câu hỏi ngớ ngẩn ... nhưng bạn có ý gì khi kiểm tra đường ruột ba lần? – mattruma

+0

Ý tôi là sớm và tôi chưa có cà phê. ;-) Tôi có nghĩa là bạn đã kiểm tra lại định nghĩa của tệp dbml của bạn (các kiểu dữ liệu, nullable, các mối quan hệ) đối với db của bạn? –

Trả lời

2

Tôi đã tìm ra sự cố của mình với sự trợ giúp của cộng đồng SO. Vấn đề của tôi đã được gây ra bởi thực tế khi tôi tạo ra thực thể của tôi để đính kèm, giá trị mặc định của cột được thiết lập để không, do đó, khi nó đã cố gắng để gán giá trị cho số không ... LinqToSql nói hey ... không có gì thay đổi, vì vậy Tôi không cập nhật giá trị.

Tôi đang làm gì bây giờ ...chỉ để làm cho nó hoạt được như sau:

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

Đó dường như để buộc tất cả các giá trị để viết bản thân cơ sở dữ liệu. Điều này làm việc cho bây giờ.

3

Tôi đã cố gắng tạo lại mã này bằng một mã sau đây, nhưng đối với tôi nó hoạt động.

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

Vì vậy, tôi nghĩ phải có điều gì đó đặc biệt trong miền của bạn gây ra điều này. Tôi đề nghị bạn tạo một repro đơn giản như vậy với mô hình miền của bạn và xem điều gì xảy ra.

LINQ to SQL bỏ qua các cập nhật cho giá trị hiện tại, vì vậy nếu trường đã bằng 0, bạn có thể không thấy bất kỳ cập nhật nào.

Tắt: OR/M bạn sử dụng là LINQ to SQL. LINQ là tên của khả năng truy vấn trong .NET, nhưng LINQ không định nghĩa và cũng không thực hiện bất kỳ logic cập nhật nào. Vì vậy, vấn đề liên quan đến LINQ to SQL, không phải LINQ.

+0

Cảm ơn! Tôi sẽ kiểm tra điều này! – mattruma

+0

Bạn đã đúng trên @Gaspar Nagy ... LINQ to Sql đã bỏ qua sự thay đổi. – mattruma

2

Câu hỏi rõ ràng, nhưng bạn có chắc chắn cột được ánh xạ trong tệp dbml/ánh xạ không?

Ngoài ra - đó có phải là cột được tính toán không? (ví dụ: giá = > đơn vị * đơn vị)

2

Một số biết thêm thông tin ... tôi đã tìm ra vấn đề của tôi ... đó là chi tiết của một thiếu hiểu biết về LinqToSql ... nơi tôi đang làm:

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 
      } 
    } 
} 

Tôi nghĩ điều này sẽ tải các giá trị ban đầu ... những gì xảy ra là nó tạo ra một đối tượng mới với giá trị mặc định ... giá trị rỗng, như 0 cho số thập phân, Guid.Empty cho uniqueidentifiers và như vậy.

Vì vậy, khi cập nhật các thuộc tính, nó sẽ thấy các Đơn vị đã bằng 0 và nó đặt thành 0. Vâng LinqToSql không nhận ra điều này như là một sự thay đổi vì vậy nó không lên ngày lĩnh vực này. Vì vậy, những gì tôi đã phải làm là như sau:

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

Bây giờ tất cả các sửa đổi được tạo ra trong bản cập nhật cho dù thực sự có thay đổi hay không. Điều này hoạt động ... có vẻ hơi hack!

0

Tôi gặp sự cố này và tất cả các đề xuất tôi đã thấy không áp dụng hoặc không hoạt động.

Nhưng tôi thấy mình đã mắc phải một sai lầm rất đơn giản!

Khi cập nhật thuộc tính, tôi đã thực sự gọi phương thức Đặt tùy chỉnh (vì có những thứ khác cần phải được thay đổi để phản hồi lại thuộc tính chính được đề cập).

Sau giờ làm xước đầu, tôi nhận thấy rằng phương pháp Set của tôi đang cập nhật thành viên riêng tư không phải là tài sản công cộng, tức là this._Walking = value;

Tất cả những gì tôi phải làm là thay đổi điều này thành giá trị này.Walking = value; và tất cả bắt đầu hoạt động!

1

Câu trả lời chính xác được như nhiều chỉ ra sử dụng quá tải đặc biệt của Đính kèm mà chấp nhận một tham số boolean để xem xét nó như là sửa đổi, (mắc sai lầm khi sử dụng quá tải khác và nó chỉ đơn giản là sẽ không làm việc):

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

Lưu ý rằng bạn vẫn có thể cần cột "Phiên bản" trong bảng loại "dấu thời gian".

Các vấn đề liên quan