0

오랜 질문에 사과드립니다. 그러나 모든 세부 사항을 알려주는 것이 중요하므로 끝까지 끝까지 견뎌주십시오.FluentNHibernate - 클래스를 여러 테이블에 매핑하기

저는 많은 권한이없는 레거시 데이터베이스를 사용하고 있습니다. 클래스를 여러 데이터베이스 테이블에 매핑 할 수 있어야합니다. 여기 내 테이블 당신이 볼 수 있듯이, 나는 모든 조회가 저장되는 조회 테이블을

Lookup

+--------+--------------+------------+ 
| Column | DataType | Attributes | 
+--------+--------------+------------+ 
| Id  | INT   | PK   | 
| Code | NVARCHAR(50) |   | 
+--------+--------------+------------+ 

Culture

+--------------+--------------+------------+ 
| Column | DataType | Attributes | 
+--------------+--------------+------------+ 
| Id   | INT   | PK   | 
| Culture_Code | NVARCHAR(10) |   | 
+--------------+--------------+------------+ 

Lookup_t9n

+----------------+---------------+---------------------+ 
|  Column  | DataType |  Attributes  | 
+----------------+---------------+---------------------+ 
| Id    | INT   | PK     | 
| Culture_Id  | INT   | FK to Culture table | 
| Localised_Text | NVARCHAR(MAX) |      | 
+----------------+---------------+---------------------+ 

보는 방법이다. 찾아보기의 표시 텍스트는 현지화되어 별도의 테이블에 저장됩니다. 이 테이블에는 현지화 된 텍스트가있는 문화권을 나타내는 외래 키 키가 있습니다.

내 클래스는이

public class Lookup { 

    public virtual int Id {get; set;} 

    public virtual string Code {get; set;} 

    public virtual string DisplayText {get; set;} 
} 

처럼 보인다 그리고 내 FNH 매핑 클래스는 Join 부분에 좀를 제공하려면, 위의 매핑이

public class LookupMappings : ClassMap<Lookup> { 

    public LookupMappings() 
    { 
     Table("Lookup"); 
     Id(x => x.Id).Column("Id"); 
     Map(x => x.Code).Column("Code"); 

     Join("Lookup_t9n", join => { 
      join.Map(x => x.DisplayText).Column("Localised_Text"); //Note this place, my problem is here 
     }) 
    } 
} 

처럼 보이는 where 절 WHERE Lookup_t9n.Culture_Id = Culture.Culture_Id AND Culture.Culture_Code = System.Threading.Thread.CurrentUICulture.CultureCode있다.

나는 이것이 유효한 SQL이 아니라는 것을 알고 있지만 의도를 전달합니다. 그런 일을 한 경험이있는 사람이 있습니까?

데이터베이스 테이블과 일대일 매핑하는 클래스를 가질 수있는 매핑 계층을 추가 한 다음 일반 클래스를 작성하여 해당 클래스를 다시 Lookup 클래스에 매핑 할 수 있습니다. 나는 중간 솔루션으로 오히려 그것을 해왔다. 스마트 NH 사용으로 맵핑 레이어를 제거 할 수 있는지 궁금합니다.

답변

1

간단한 대답이 없습니다. 예를 들어 CallThis()입니다. 유사한 자료를 사용하는 방법에 따라 제안을하고 싶습니다. 이 솔루션은 표준 매핑을 기반으로하므로 C# 엔티티의 복잡성을 피할 수 있습니다. 이 솔루션의 단지 초안 그래서

(... CS, 도중 것은)의이 보자 중앙 문화 테이블을 건너 뛸 것이고, Lookup_t9n에 우리가 문화의 이름을 저장 할 것으로 기대 것이다 이 갖는 클래스는

public class Lookup { 
    public virtual int Id {get; set;} 
    public virtual string Code {get; set;} 
            // for simplicity skipping null checks  
    public virtual DisplayText { get { return Localizations.First().LocalizedText; } } 
    public virtual IList<Localization> Localizations {get; set;} 
} 

public class Localization { // mapped to Lookup_t9n 
    public virtual string CultureName {get; set;} 
    public virtual string LocalizedText {get; set;} 
} 

, 우리는 HasManyLocalizations수집을 매핑 할 수 있습니다. 심지어 구성 요소로 매핑 될 수도 있습니다. (example of component mapping 참조)

이제 우리는 필터를 도입해야합니다. Example with Fluent. 필수 문서 : 18.1. NHibernate filters.

단순화 된 매핑

필터 :

public class CulturFilter : FilterDefinition 
{ 
    public CulturFilter() 
    { 
    WithName("CulturFilter") 
     .AddParameter("culture",NHibernate.NHibernateUtil.String); 
    } 

가 수집 :

HasMany(x => x.Localization) 
    .KeyColumn("Id") 
    ... 
    .ApplyFilter<CulturFilter>("CultureName = :culture")) 
    .Cascade.AllDeleteOrphan(); 

마지막으로, 우리는 몇 가지 AOP 필터를 도입해야 할 때마다 트리거됩니다 IInterceptor ...이 (필요) 조정 후 조정하십시오. ISession

session 
    .EnableFilter("CulturFilter") 
    .SetParameter("culture" 
    ,System.Globalization.CultureInfo.CurrentCulture.TwoLetterISOLanguageName); 

그리고 현재 문화권을 기반으로 한 문자열은 Localized이며 현지화 된 값을 모음으로 사용합니다.

+0

나는 당신의 솔루션을 두 번이나 이미 돌아가려고 노력했습니다. 나는 당신이 제공 한 모든 링크를 통해 먼저 그것을 구현해야한다고 생각합니다. – Suhas

+0

동의합니다. 내 쇠약은 당신이 원하는만큼 간단하지 않습니다. 그러나 그것은 결국 일하고 있습니다 ... –