2009-07-01 72 views
11

我正在與一個簡單的實體類與LINQ to SQL(SQL Server 2005 SP3 x64)。LINQ to SQL實體列名稱屬性忽略與GUID主鍵

[Table(Name="TBL_REGISTRATION")] 
public sealed class Registration : IDataErrorInfo 
{ 
    [Column(Name = "TBL_REGISTRATION_PK", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
    public Guid RegistrationID { get; private set; } 
    /* other properties ommited for brevity */ 
} 

只有兩個在這裏有些有趣的事情:

  1. 類和屬性名稱不一樣的表和列名
  2. 主鍵是一個GUID(唯一標識符)

這裏的表是什麼樣子:

create table dbo.TBL_REGISTRATION 
    (
    TBL_REGISTRATION_PK uniqueidentifier primary key clustered 
     rowguidcol 
     default newid(), 
    /* other columns ommited for brevity */ 
    ) 

當我將這個附加實體到我的表,我的DataContext提交更改時,LINQ堆棧拋出回的SQLException:

SQLEXCEPTION(0x80131904):無效的列名稱RegistrationID「

LINQ似乎被忽略我的RegistrationID屬性上的Column(Name =「TBL_REGISTRATION_PK」)屬性。我花了一段時間用不同的屬性裝飾品試圖讓它起作用。最後,我決定使用私人的TBL_REGISTRATION_PK屬性來包裝我的RegistrationID屬性,以使LINQ感到滿意。

[Table(Name="TBL_REGISTRATION")] 
public sealed class Registration : IDataErrorInfo 
{ 
     public Guid RegistrationID { get; private set; } 
     [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
     private Guid TBL_REGISTRATION_PK { get { return RegistrationID; } set { RegistrationID = value; } } 
    /* other properties ommited for brevity */ 
} 

This works。

爲什麼第一種方式不起作用?我在這裏做錯了什麼,或者這是一個LINQ缺陷?

回答

0

您是否嘗試過使用Storage屬性?

[Table(Name="TBL_REGISTRATION")] 
public sealed class Registration : IDataErrorInfo 
{ 
     [Column(Name="TBL_REGISTRATION_PK", Storage="_RegistrationID", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
     public Guid RegistrationID { get { return _RegistrationID; } set { _RegistrationID = value; } } 

     private Guid _RegistrationID; 
    /* other properties ommited for brevity */ 
} 

參見Attribute-Based Mapping (LINQ to SQL)

+0

都能跟得上。好主意,但是definetly不起作用:「無效的列名'RegistrationID'。」 – 2009-07-08 19:17:21

0

使用 「存儲」 屬性,與列名:

[Column(Name="TBL_REGISTRATION_PK", Storage="TBL_REGISTRATION_PK", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
     public Guid RegistrationID { get { return _RegistrationID; } set { _RegistrationID = value; } } 

因爲列的存儲名字是TBL_REGISTRATION_PK。

+0

感謝您的參與,但這並不奏效。這將導致InvalidOperationException在運行時被拋出,因爲類中沒有「TBL_REGISTRATION_PK」字段或屬性。 ColumnAttribute.Storage屬性用於指示一個私有字段,該字段保存支持您用屬性裝飾的屬性的數據。 – 2009-07-10 15:40:18

2

您的財產需要'私人'從'私人設置'中移除;'當你在VS 2008中創建簡短的屬性而不實現get/set時,編譯器爲你創建私有成員變量(誰知道哪個名字)。 ColumnAttribute中的存儲選項指定要使用哪個私有成員。

Linq to SQL不知道如何設置該屬性,如果您將setter私有標記爲public並且getter公開(不要問我爲什麼)。如果你想讓你的財產只讀,請像上面做的那樣創建一個私有成員變量。

你可以這樣寫它清理以下內容:

[Table(Name="TBL_REGISTRATION")] 
    public sealed class Registration : IDataErrorInfo 
    { 
      public Guid RegistrationID { get { return _registrationID; } } 

      [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
      private Guid _registrationID; 
} 
+1

這是否解決您的問題? – jonathanpeppers 2009-07-22 13:37:04

0

,我已經找到解決這個問題的最佳解決方案是在具有完全相同的名稱作爲類來創建一個私人的Guid場數據庫中的主鍵,並將其用作符合框架指南命名約定的屬性的支持字段。

// Primary key to TBL_REGISTRATIONT 
[Column(Name = "TBL_REGISTRATIONT_PK", IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
public Guid RegistrationID 
{ 
    get 
    { 
     return TBL_REGISTRATIONT_PK; 
    } 
    private set 
    { 
     TBL_REGISTRATIONT_PK = value; 
    } 
} 
[Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
private Guid TBL_REGISTRATIONT_PK;