2009-07-01 13 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 */ 
} 

ここでは2つだけやや面白いものがあります。

  1. クラスとプロパティ名は、テーブル名とカラム名
  2. と同じではありません主キーにGUID(UNIQUEIDENTIFIER)であるが

ここでは、テーブルは次のようになります。

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プロパティを解決し、LINQを満足させるためにRegistrationIDプロパティをラップしました。

[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の欠陥ですか?

答えて

0

Storageプロパティを試しましたか?列のストレージ名がTBL_REGISTRATION_PKあるので

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

:また

[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

いいえ。良いアイデアが、しかし、間違いなく動作しません: "無効な列名 'RegistrationID'。" –

0

は、列の名前で、 "ストレージ" プロパティを使用してください。

+0

再生してくれてありがとうございますが動作しません。クラスに "TBL_REGISTRATION_PK"フィールドまたはプロパティがないため、実行時にInvalidOperationExceptionがスローされます。 ColumnAttribute.Storageプロパティは、属性で装飾しているプロパティをバックアップするデータを保持するプライベートフィールドを示すためのものです。 –

2

あなたのプロパティのニーズは「プライベート」が「プライベートセット」から削除されました。 get/setを実装せずにVS 2008でショートハンドプロパティを作成すると、コンパイラは(あなたが知っている名前の)あなたのためのプライベートメンバ変数を作成します。 ColumnAttributeのStorageオプションは、使用するプライベートメンバーを指定します。

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; 
} 
+1

これで問題は解決しますか? – jonathanpeppers

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; 
関連する問題