【问题标题】:LINQ to SQL entity column name attribute ignored with guid primary key使用 guid 主键忽略 LINQ to SQL 实体列名属性
【发布时间】:2010-11-07 05:25:05
【问题描述】:

我正在使用带有 LINQ to SQL (SQL Server 2005 SP3 x64) 的简单实体类。

[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 */
}

这行得通。

为什么第一种方式不起作用?我在这里做错了什么还是这是 LINQ 缺陷?

【问题讨论】:

    标签: c# sql-server linq sql-server-2005 linq-to-sql


    【解决方案1】:

    这是 Linq-to-SQL 中的一个错误。它已在 .net 4.0 中修复。

    请参阅连接 #381883: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=381883

    【讨论】:

    • 我很高兴终于发现(a)我没有疯,(b)它正在修复中。
    【解决方案2】:

    您的财产需要从“私人集”中删除“私人”;当您在 VS 2008 中创建简写属性而不实现 get/set 时,编译器会为您创建私有成员变量(谁知道的名称)。 ColumnAttribute 中的 Storage 选项指定使用哪个私有成员。

    如果您将 setter 标记为私有并让 getter 公开(不要问我为什么),Linq to SQL 不知道如何设置属性。如果您希望将您的属性设为只读,请像上面那样创建一个私有成员变量。

    你可以像下面这样写来清理它:

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

    【讨论】:

      【解决方案3】:

      您是否尝试过使用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)

      【讨论】:

      • 不。好主意,但这绝对行不通:“列名 'RegistrationID' 无效。”
      【解决方案4】:

      使用“Storage”属性,以及列的名称:

      [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。

      【讨论】:

      • 感谢您的参与,但这不起作用。它将导致在运行时抛出 InvalidOperationException,因为类中没有“TBL_REGISTRATION_PK”字段或属性。 ColumnAttribute.Storage 属性用于指示一个私有字段,该字段包含支持您使用该属性装饰的属性的数据。
      【解决方案5】:

      我发现这个问题的最佳解决方案是在类中创建一个私有 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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-13
        相关资源
        最近更新 更多