2011-09-15 23 views
1

現在この問題に直面しています。私はSQLにLINQを介して自分のデータベーステーブルにPOCOを手動でマッピングしました。これらのオブジェクト/テーブルをすべて1つのコンテキスト(トランザクションとして扱う)に配置して、トランザクションで障害が発生した場合にすべてがロールバックされるようにしたいと思います。LINQ to SQL 1:1挿入

私が直面している問題は、UserLoginとUserProfile(1:0 - 1の関係)です。それらは、UserLoginのIDがPKであり、FKがUserProfileであり、UserProfileで同じであるように構成されています。 UserLoginでは、IsDBGeneratedをtrueに設定してIDを自動的に生成するように設定されています。一方、UserProfileにはIsDBGeneratedがありません。

UserProfileはUserLoginのEntityRefとして設定され、同じコンテキストから来るため、作成時にUserLogin.UserProfile = new UserProfile()を設定します。

すべてのプロパティを割り当てた後、table.InsertOnSubmit(UserLogin)およびcontext.SaveChanges()を実行しました。

本当の問題の出番です。のUserProfileのidが0

として残っている誰もが助けることはできますか?


申し訳ありませんが、私は明らかにしませんでした。 1の関係 - 0:使用しているSQL ServerがMS SQL Server 2008の

は、エンティティの構造は次のようになっているのUserProfileがいない間、

userloginのは1作り、サインアップ時に必須です。したがって、両方のテーブルで自動インクリメントを使用することは賢明ではありません。

UserProfileのPKもUserLoginを参照するFKです。

@GertArnoldはい、私はUserProfile id = UserLogin idをasp.netコードビハインドに設定しましたが、コンテキストが保存される前に、UserLoginのIDは0のままです。この時点で、両方のレコードを一緒に追加したいLinqがSqlにこれを解決する何らかの方法があるのだろうかと疑問に思います。私はAssociation属性を追加したので、SqlのLinqはこの依存関係を認識して、送信時にIDを追加する必要があります。少なくとも、それは私の希望的な考え方です。

私のUserProfileで

、私はこのスニペット持っている:私のuserloginので

[Column(IsPrimaryKey = true)] 
public long id { get; set; } 
private EntityRef<UserLogin> _login; 
[Association(ThisKey = "id", Storage = "_login")] 
public UserLogin UserLogin { get { return _login.Entity; } 
    set { _login.Entity = value; } } 

を、私は次のスニペットがあります

[Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
public long id { get; set; } 
private EntityRef<UserProfile> _profile; 
[Association(ThisKey = "id", Storage = "_profile")] 
public UserProfile UserProfile { get { return _profile.Entity; } 
    set { _profile.Entity = value; } } 

最後に、私の中でコードビハインド、私はこれを持っている:

UserLogin login = new UserLogin(); 
// All assigning here 
login.UserProfile = new UserProfile(); 
// Assign here 
login.userProfile.id = login.id; 

この時点では、どちらのIDもまだ挿入されていないため、両方のIDはゼロです。

私はcontext.SubmitChanges()を実行すると、UserLoginのIDは値が増えますが、UserProfileのIDは0になります。同じコンテキストで両方を折り返して一緒に送信したい理由は、UserLoginがユーザプロファイルはエラーを起こします。だから私のDBには、ログインのためのレコードがありますが、私のデータを混乱させるプロファイルはありません。

+0

どのようなタイプのデータベースを使用していますか? UserProfileはUserLoginの子レコードです(少なくともそれは私のようです)なぜあなたはUserProfile.IdをSqlServerのAutoIncremtingフィールドにする必要がありますか? – esastincy

答えて

2

あなたは何を得ているのかを理解するために、この質問を何度も読まなければなりませんでした。このライン

彼らはuserloginののidはのUserProfileにPKやFKをされ、同じことが

のUserProfile

のために行く方法で構成されているが、当初 UserLoginは、 UserProfileへの外部キーを持っていることを意味するように見えました UserProfileには、 UserLoginへの外部キーがあります。しかし、今私はあなたがしようとしているのは、両方のテーブルのPKに同じ値を使うことだと思います。もし私が UserLoginId = 123を持っていたら、私はプロファイルを作成したいと思っています。 UserProfileId 123.

なぜあなたはこれをやっていますか? LINQ-to-SQLは、データベースの観点からは問題ありませんが(特に有益ではなく、やや紛らわしいと主張しています)、LINQ-to-SQLはプライマリキーとして使用されず、他のテーブルの場合また、主キーでもない外部キーが必要です。

UserProfileテーブルの値123は、実際にはUserLoginの外部キーですが、プライマリキーではありません。これはプライマリキーである必要はなく、LINQ-to-SQLの処理を混乱させるようにしています。 UserProfileには独自のPKがあります。自動インクリメントのIDを作成し、外来キーとなるものをUserLoginに変更します。すべての問題が解決されます。私の経験で

UserLogin 
PK - UserLoginId int identity 

UserProfile 
PK - UserProfileId int identity 
FK - UserLoginId int 

、両方のLINQツーSQL & Entity Frameworkのシンプルな代理の主キーを使用して最高の仕事 - 他のすべての独立しました。あまりにも扱いにくいものや非標準的なものがあれば、知覚される利点やシンプルさよりも頭痛が増すことがあります。

+0

あなたはそう正しいです。それは私が意図していることです、代理キーをスキップして、UserProfileのid = UserLoginのIDを作ることです。 EFでは、私は流暢なAPIで遊んでこれを達成することができましたが、L2Sではそうはできませんでした。悲しいことに、このプロジェクトはまだL2Sに固執しています。それでは、私はそれをEF4.1に変換することに苦労するでしょう。とにかく私のDBAへのアプローチを提案し、そこからどうやって行くのかを見てみましょう。ありがとう。 –

+0

私はこれを行う必要がある場合、私は、リレーショナルデータベースでハードコーディングされた1対1の関係を失うことになるだろう、私は同じ問題(下記のリンク)を持っている。これは、その重要な制約を破ることが可能であることを意味します。 http://stackoverflow.com/questions/10212290/linq-one-to-one-association-submitchanges –

+0

@andicrookあなたの質問は削除されましたので、私はコメントできません。しかし、私は完全には同意しません.1:1を保証するために外部キー列に一意の制約を追加できます。 –