2011-09-15 99 views
1

我目前正面臨這個問題。我通過LINQ to SQL將POCO手動映射到我的數據庫表中。我希望將所有這些對象/表放在一個上下文中(作爲事務處理),以便在事務中出現故障時,所有對象都會回滾。LINQ to SQL 1:1插入

現在我面臨的問題是我有UserLogin和UserProfile(1:0 - 1關係)。它們以UserLogin的ID爲UserProfile的PK和FK的方式構建,UserProfile也是如此。在UserLogin上,它被設置爲自動生成IsDBGenerated設置爲true的標識。 UserProfile另一方面沒有IsDBGenerated。

UserProfile在UserLogin中設置爲EntityRef,並且由於它們來自同一個上下文,所以在創建時我會設置UserLogin.UserProfile = new UserProfile()。

分配所有屬性後,我做了table.InsertOnSubmit(UserLogin)和context.SaveChanges()。

這是真正的問題用武之地。用戶配置的ID仍然爲0。

誰能幫助?


對不起,我沒有說清楚。在使用中的SQL Server是MS SQL Server 2008的

的實體結構是這樣的,

用戶登陸是在註冊時必需的,而用戶配置不是,使其成爲1:0 - 1的關係。因此,在兩個表上都有自動增量是不明智的。

UserProfile的PK也是引用UserLogin的FK。

@GertArnold,是的,我沒有在asp.net代碼後面設置UserProfile id = UserLogin id,但在上下文保存之前,UserLogin的id將保持爲0,因爲此時我希望將兩個記錄添加到一起,想知道Linq to Sql是否有辦法解決這個問題。因爲我已經添加了Association屬性,所以通過右邊的Linq to Sql應該可以識別這個依賴關係,並在提交時添加該id,或者至少,這是我的一廂情願。

在我的用戶配置,我有這樣的片段:

[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都爲零,因爲它們都沒有被插入。

當我做context.SubmitChanges()時,UserLogin的id將得到遞增的值,但UserProfile的id將保持爲0.我想將兩者包裝在同一個上下文中並提交在一起的原因是爲了避免像UserLogin這樣的情況出現提交,但UserProfile發生錯誤。所以在我的數據庫中,有一條登錄記錄,但沒有配置文件,搞亂了我的數據。

+0

您使用的是哪種類型的數據庫?由於UserProfile是UserLogin的子記錄(至少在我看來是這樣),爲什麼你不能只有UserProfile.Id是SqlServer中的一個AutoIncremting字段,如果它的Oracle ...添加一個序列...? – esastincy

回答

2

我不得不多次閱讀這個問題,以瞭解你所得到的。這條線

他們的方式,其中用戶登陸的ID是PK和FK到用戶配置和同樣的用戶配置

結構最初似乎意味着UserLogin有一個外鍵UserProfileUserProfile有一個外鍵UserLogin。但是我現在認爲你要做的是在兩個表中使用相同的PK值;如果我有UserLoginId = 123,然後我創建一個配置文件,你希望我有UserProfileId 123.

你爲什麼要這樣做?從數據庫的角度來看沒什麼問題(儘管我認爲這並不是特別有益,而且有點令人困惑),但是LINQ-to-SQL需要一個主鍵,它知道它是單個行的主鍵,而不是用作主鍵對於任何其他表格。它需要一個不是主鍵的外鍵。

UserProfile表中的值123實際上是UserLogin的外鍵,但不是主鍵。它不需要成爲主鍵,因此您可以通過這樣做讓LINQ-to-SQL更容易混淆。讓UserProfile有它自己的PK。創建一個自動遞增的身份,並將您必須成爲的外鍵改回UserLogin。你所有的問題都將得到解決。

UserLogin 
PK - UserLoginId int identity 

UserProfile 
PK - UserProfileId int identity 
FK - UserLoginId int 

以我的經驗,無論是LINQ到SQL &實體框架的工作最好用簡單的代理主鍵 - 獨立的一切的。任何棘手或非標準的事情都可能會讓你感到頭痛,而不是任何感覺到的益處或簡單。

+0

是的,你有這個權利。這正是我打算做的,使UserProfile的id = UserLogin的id,跳過代理鍵。在EF中,我能夠通過流暢的API來實現這一目標,但不能在L2S中實現。不幸的是,這個項目仍然堅持L2S,如果我決定將其轉換爲EF4.1,那麼這將會讓我很難過,無論如何,我會向DBA建議您的方法,並看看我們如何從那裏開始。謝謝。 –

+0

我有同樣的問題(下面的鏈接),如果我將不得不這樣做,那麼我將失去關係數據庫中的硬編碼一對一關係。這意味着可以打破這個重要的限制。 http://stackoverflow.com/questions/10212290/linq-one-to-one-association-submitchanges – 2012-04-18 15:46:37

+0

@andicrook你的問題已被刪除,所以我不能評論。但我並不完全同意 - 你仍然可以在外鍵列上添加一個唯一的約束來確保1:1。 –