2009-03-12 77 views
6

Tôi đang sử dụng LINQ to SQL. Tôi có một DataContext mà tôi đang dùng .SubmitChanges() 'ing. Có một lỗi khi chèn lĩnh vực nhận dạng: LINQ to SQL: Tại sao tôi gặp lỗi IDENTITY_INSERT?

Cannot insert explicit value for identity column in table 'Rigs' when IDENTITY_INSERT is set to OFF.

Các lĩnh vực nhận dạng duy nhất là "ID", trong đó có một giá trị 0. Nó được định nghĩa trong DBML như:

[Column(Storage="_ID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] 

Có một vài ngoại và tôi đã xác minh rằng họ có các giá trị hấp dẫn với nội dung của bảng ngoại.

Tại sao tôi gặp phải lỗi này?

Edit: Đây là truy vấn:

exec sp_executesql N'INSERT INTO [dbo].[Rigs]([id], [Name], [RAM], [Usage], [MoreInfo], [datetime], [UID]) 
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6) 
SELECT [t0].[id], [t0].[OSID], [t0].[Monitors] 
FROM [dbo].[Rigs] AS [t0] 
WHERE [t0].[id] = @p7',N'@p0 int,@p1 varchar(1),@p2 int,@p3 varchar(1),@p4 varchar(1),@p5 datetime,@p6 int,@p7 
int',@p0=0,@p1='1',@p2=NULL,@p3='4',@p4='5',@p5=''2009-03-11 20:09:15:700'',@p6=1,@p7=0 

Rõ ràng nó đang đi qua một số không, mặc dù đã bao giờ được gán một giá trị.

Chỉnh sửa: Thêm Code:

Rig rig = new Rig(); 
int RigID; 
try 
{ // Confirmed these always contain a nonzero value or blank 
    RigID = int.Parse(lbSystems.SelectedValue ?? hfRigID.Value); 
    if (RigID > 0) rig = mo.utils.RigUtils.GetByID(RigID); 
} 
catch { } 

rig.Name = Server.HtmlEncode(txtName.Text); 
rig.OSID = int.Parse(ddlOS.SelectedValue); 
rig.Monitors = int.Parse(txtMonitors.Text); 
rig.Usage = Server.HtmlEncode(txtUsage.Text); 
rig.MoreInfo = Server.HtmlEncode(txtMoreInfo.Text); 
rig.RigsToVideoCards.Clear(); 
foreach (ListItem li in lbYourCards.Items) 
{ 
    RigsToVideoCard r2vc = new RigsToVideoCard(); 
    r2vc.VCID = int.Parse(li.Value); 
    rig.RigsToVideoCards.Add(r2vc); 
} 
rig.UID = c_UID > 0 ? c_UID : mo.utils.UserUtils.GetUserByToken(this.Master.LiveToken).ID; 

if (!mo.utils.RigUtils.Save(rig)) 
    throw new ApplicationException("There was an error saving your Rig. I have been notified."); 
hfRigID.Value = rig.id.ToString(); 

public static User GetUserByToken(string token) 
{ 
    DataClassesDataContext dc = new DataClassesDataContext(ConfigurationManager.ConnectionStrings["MultimonOnlineConnectionString"].ConnectionString); 
return (from u in dc.Users 
    where u.LiveToken == token 
    select u).FirstOrDefault(); 
} 

Ngoài ra, tôi nhận thấy rằng khi tôi cập nhật một giàn khoan hiện có (InsertOnSubmit), nó không cập nhật. Profiler thậm chí không hiển thị bất kỳ truy vấn nào đang chạy.

+0

Bạn có thể đưa mã vào nơi bạn tạo đối tượng và thêm nó vào DataContext không? – Portman

+0

Tôi thứ hai Portman, xin vui lòng gửi mã bạn đang sử dụng cho chèn, xem câu trả lời của tôi, nó có khả năng vấn đề là ở đó – eglasius

Trả lời

7

Mã của bạn có đặt giá trị ID rõ ràng là 0 không? (thay vì để nó bị ảnh hưởng).

Cập nhật 1: Khi bạn đăng trên phiên bản cập nhật, linq2sql rõ ràng chuyển giá trị cho db. Dưới đây là một trong tôi đã không có bất kỳ rắc rối với:

[Column(Storage="_CustomerID", AutoSync=AutoSync.Always, DbType="Int NOT NULL IDENTITY", IsDbGenerated=true)] 
public int CustomerID 

Tôi chỉ thấy nhau, và nó có định nghĩa chính xác cùng một trong những bạn đang sử dụng.

[Column(Storage="_TestID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] 
public int TestID 

Cập nhật 2: Về bản cập nhật, bạn không phải làm InsertOnSubmit cho điều đó. Chỉ cần cập nhật các giá trị và gọi .SubmitChanges (cần phải ném một ngoại lệ). Trên chèn nó thực sự là lạ, như các thuộc tính tài sản bạn đăng có vẻ là chính xác, do đó, các linq2sql Chèn phương pháp tạo ra nên được chính xác là tốt. Tôi sẽ cố gắng, thêm lại bảng trên thiết kế một lần nữa và xác minh tất cả các thuộc tính là chính xác.

Lưu ý rằng phương pháp chèn tạo ra sẽ giống như thế (với một matchingRig_Insert):

private void InsertRig(Rig obj) 
{ 
    System.Nullable<int> p1 = obj.Id; 

this.Rig_Insert (/ * bó của các giá trị * /, ref p1); obj.Id = p1.GetValueOrDefault(); }

+0

Ngoại trừ định nghĩa thứ hai có "IsPrimaryKey = true", thêm vào nó. – Chris

+0

@ Chris, tôi đã nói định nghĩa được lấy mẫu là định nghĩa mà anh ấy đang sử dụng;) – eglasius

+0

@Freddy, tha thứ cho sự thiếu hiểu biết của tôi, tôi mệt mỏi vì công việc, chúng giống nhau như thế nào? – Chris

1

Nếu bạn đang cung cấp giá trị của cột IDENTITY, bạn phải thêm

SET IDENTITY_INSERT ON 

trước câu lệnh SQL của bạn, và

SET IDENTITY_INSERT OFF 

sau để tắt nó đi. Điều đó xảy ra với bất kỳ SQL thô nào.Nếu bạn đã sử dụng LINQ để tạo một đối tượng như:

var customer = new LinqContext.Customer; 
customer.FirstName = "Bob"; 
customer.LastName = "Smith"; 

LinqContent.Customer.Add(customer); 
LinqContext.SubmitChanges(); 

Tôi tin rằng sẽ làm việc, tha thứ cho tôi nếu tôi có lớp học sai. Bạn nhận được ý tưởng cơ bản.

Chỉnh sửa: Rất tiếc .. Xin lỗi, không đọc toàn bộ câu hỏi, tôi mang nó về, mệt mỏi và mệt mỏi từ công việc ...

+0

ông không làm điều đó vào mục đích, mà sẽ gây ra nó để chèn 0 ... sau đó không cho chèn trùng lặp – eglasius

1

có vẻ như ID của bạn đang được giao ở đâu đó (ngay cả khi chỉ mặc định cho 0) - bạn có quan tâm đến việc đăng một số mã LINQ của bạn không?

2

Đảm bảo thuộc tính Giá trị được tạo tự động trong dbml của bạn cho cột đó được đặt thành true. Nếu không, LINQ sẽ cố gắng để mặc định giá trị dựa trên loại.

10

lý thuyết của tôi về những gì đã xảy ra như sau:

  1. Bạn thiết kế và tạo ra cơ sở dữ liệu
  2. Bạn đã tạo Context DB dùng LINQ to SQL trong Visual Studio
  3. Bạn quên để thiết lập auto nhận dạng bảng của bạn
  4. Bạn đã khắc phục điều đó bằng cách chuyển đến DataBase và đặt tự động nhận dạng
  5. Nhưng bạn quên tạo lại/cập nhật LINQ TO SQL DB Context !!!

: D

+0

Chính xác những gì nó đã được! – joshmcode

+0

bạn thực hiện ngày của tôi :) –

+0

Cảm ơn bạn! Đã đập đầu của tôi chống lại chính xác điều này rối tung xung quanh trong LinqPad. –

0

Tôi đã có vấn đề chính xác như vậy.

Giải pháp của tôi là tự tạo cột nhận dạng INT thành giá trị rỗng INT? cột trong thiết kế DBML, không phải trong bảng thực tế của DB của khóa học. Ngoài ra, đặt DbType thành NULL thay vì NOT NULL. Giống như vậy:

[Column(Storage="_TestID", AutoSync=AutoSync.OnInsert, DbType="Int NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] 
public int? TestID 

Điều này làm việc với tất cả các hoạt động DB. Khi chèn chỉ cần đặt cột nhận dạng thành NULL thay vì là 0.

0

trường hợp của tôi, tôi quên cập nhật tệp dbml sau khi đặt cột Id thành nhận dạng.