2009-04-14 3 views
1

의 내가 세 개의 테이블이 있다고 가정 해 봅시다 : 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 파일을 만들 때 데이터베이스에 설정된 외래 키에 따라 사용자를 UserSettingUserSetting에서 Setting으로 적절하게 연결합니다.

사용자가 특정 값을 의미있는 방식으로 재정의하지 않은 경우 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 꽤 아래로 무식하게 유지하고, 어떤 화려한 요구 사항을 추가 할을 내 부분 수업, 다음과 같은 내가 사용하는 솔루션입니다.

내가 내 사용자 클래스에 다음 헬퍼를 추가 (작동 있도록 호세의 답변에 따라,하지만 고정) : 다음 할 수있는

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

완벽하게 작동했습니다. 내가 도왔다 고 생각했던 작은 조정 하나를 만들었습니다.linq 쿼리에서 IsDefault를 설정하는 대신 SettingValue에서 get은 (Setting.Default == Value)를 반환합니다. – jerhinesmith

-1

각 사용자에 대한 모든 설정을 나타내는 UserSetting 및 Setting을 조인하는보기를 만들 수 있습니다. 그런 다음 UserSettings 연결 (또는 새 설정을 추가 할 수 없으면 작동하지 않고 UserSettings 연결을 너무 바꿀 수도 있음) 이외에 DBML 파일의보기를 사용하십시오.

나는 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