2009-04-14 9 views
1

のは、私は3つのテーブルがあるとしましょう:UserSettingLINQのツーSQL表合体は

 
ID | Name  | Default 
========================= 
1 | SettingA | ADefault 
------------------------- 
2 | SettingB | BDefault 
------------------------- 

そして

を設定

ユーザー

 
ID | Name 
=========== 
1 | UserA 
----------- 
2 | UserB 
----------- 

 
UserID | SettingID | Value 
================================ 
1  | 1  | Alice 
-------------------------------- 
1  | 2  | Bob 
-------------------------------- 
2  | 1  | AOverride 
-------------------------------- 

私は私のDBMLファイルを作成すると、それが適切にデータベースに設定し、外部キーに基づいてSettingUserSettingUserSettingにユーザーをリンクします。

ユーザーがUserSettingからSettingに戻って合意できない場合は、ユーザーが値を明確に上書きしていないと、それは可能でしょうか?

具体的には、私は次の擬似コードを探しています:

var user = MyDataContext.Users.SingleOrDefault(u => u.ID == 2); 

foreach(var setting in user.UserSettings) 
{ 
    Console.Writeline(setting.ID + "|" + setting.Value); 
} 

このような出力何かに:

 
1 | AOverride 
2 | BDefault 

変更することなく、user.UserSettingsだけ持っている値が含まれます具体的にはオーバーライドされているため返されます:

 
1 | AOverride 

それとも、それはおそらく正確ではないので、より多くの担当者が私にこれを言い換えるのを助けてくれますか? :)

答えて

3

を私はかなりダウン易しく書き直さLINQのツーSQL維持、および任意の派手な要件を追加します私の部分クラスには、私が使った解決策があります。

は、私は私のUserクラスに次のヘルパーを追加しました(それが動作するように、ホセの回答に基づいていますが、固定):私は、何ができる

public class SettingValue 
{ 
    public Setting Setting { get; set; } 
    public string Value { get; set; } 
    public bool IsDefault { get; set; } 
} 

public IEnumerable<SettingValue> GetSettingsWithDefaults(IEnumerable<Setting> settings) 
{ 
    return from s in settings 
      join us in this.UserSettings 
      on s.ID equals us.SettingID into userSettings 
      from us in userSettings.DefaultIfEmpty() 
      select new SettingValue 
        { 
         Setting = s, 
         Value = (us == null) ? s.Default : us.Value, 
         IsDefault = (us == null) 
        }; 
} 

これは新しいクラスを必要と次のようになります。

foreach(var userSetting in user.GetSettingsWithDefaults(settings)) 
{ 
    Debug.WriteLine(string.Format("Name:{0}, Value:{1}, IsDefault:{2}", 
     userSetting.Setting.Name, 
     userSetting.Value, 
     userSetting.IsDefault 
    )); 
} 

次の出力があります。

Name:SettingA, Value:OverrideA, IsDefault:False 
Name:SettingB, Value:DefaultB, IsDefault:True 
+0

これは完全に働きました。私は助けられたと思った小さな調整を1つ作った。linqクエリでIsDefaultを設定する代わりに、SettingValueのgetは単に(Setting.Default == Value)を返します。 – jerhinesmith

-1

あなたは、各ユーザーのすべての設定を表しUserSettingし、設定を結合するビューを作成することができます。その後、UserSettingsアソシエーションに加えて(または代わりに)DBMLファイルのビューを使用します(新しい設定を追加できないようにする場合を除き、UserSettingsアソシエーションを使用することはできません)。

私は、SQLサーバーが手元にないが、ビューは、おそらくこのようなものになります。

SELECT 
    User.ID AS UserID, 
    Setting.ID AS SettingID, 
    COALESCE(UserSetting.Value, Setting.Default) AS Value, 
    CASE WHEN UserSetting.UserID IS NOT NULL THEN CAST(0 AS BIT) 
     ELSE CAST(1 AS BIT) END AS IsDefault 
FROM User 
    CROSS JOIN Setting 
    LEFT JOIN UserSetting ON Setting.ID = UserSetting.SettingID 
     AND UserSetting.UserID = User.ID 
関連する問題