2009-07-01 90 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;