2009-03-03 4 views
13

나는 하나의 데이터 값 (즉 ID, 도메인 엔티티 테이블에 대한 외래 키 ID를 가지고있는 테이블에 매핑하고자하는 IList<string> 속성을 가진 도메인 클래스를 가지고있다. varchar 데이터 열).NHibernate와 문자열의 매핑을 매핑

Association references unmapped class: System.String

가 어떻게 문자열의 컬렉션에 테이블을 매핑 할 수 있습니다 :

나는 오류가 계속?

+0

되는

내가 가진 무엇 이것에 아무런 문제가 없습니다. 방금 엔티티 목록에 대해서만 작동하는 일대 다수로 매핑했습니다. derek와 Frederiks anserwers를 살펴보십시오. –

답변

22

방금 ​​비슷한 상황이 발생했습니다. 그리고 실제로 문자열 모음을 매핑하는 것이 가능하다는 것을 알았습니다. 이러한 문자열을 값 개체로 매핑해야합니다.

public class Chapter 
{ 
    private ISet<string> _synonyms = new HashedSet<string>(); 

    public ReadOnlyCollection<string> Synonyms 
    { 
     get { return new List<string>(_synonyms).AsReadOnly(); } 
    } 
} 

매핑 : 내가 잘못 생각하지 않는

<class name="Chapter" table="Chapter"> 
    <set name="Synonyms" table="ChapterSynonyms"> 
     <key column="ChapterId" /> 
     <element column="ChapterCode" type="string" /> 
    </set> 
</class> 
+10

최근에이 문제가 발생했습니다. 다음 XML 매핑을 기반으로 사용한 FluentNHibernate 매핑이 있습니다 : mapping.HasMany (x => x.Synonyms) .AsBag(). 요소 ("ChapterCode", m => m.Type ()); – roryf

+0

HashedSet이 HashShet이 아니어야합니까? –

+0

@ 당신은 가방을 사용하고 있습니다. 올바른 코드는 다음과 같아야합니다 : HasMany (x => x.Synonyms) .Table ("동의어") .AsSet (". –

1

은 당신과 같이 IUserType으로이 작업을 수행 할 수 있습니다

public class DelimitedList : IUserType 
{ 
    private const string delimiter = "|"; 

    public new bool Equals(object x, object y) 
    { 
     return object.Equals(x, y); 
    } 

    public int GetHashCode(object x) 
    { 
     return x.GetHashCode(); 
    } 

    public object NullSafeGet(IDataReader rs, string[] names, object owner) 
    { 
     var r = rs[names[0]]; 
     return r == DBNull.Value 
      ? new List<string>() 
      : ((string)r).SplitAndTrim(new [] { delimiter }); 
    } 

    public void NullSafeSet(IDbCommand cmd, object value, int index) 
    { 
     object paramVal = DBNull.Value; 
     if (value != null) 
     { 
      paramVal = ((IEnumerable<string>)value).Join(delimiter); 
     } 
     var parameter = (IDataParameter)cmd.Parameters[index]; 
     parameter.Value = paramVal; 
    } 

    public object DeepCopy(object value) 
    { 
     return value; 
    } 

    public object Replace(object original, object target, object owner) 
    { 
     return original; 
    } 

    public object Assemble(object cached, object owner) 
    { 
     return cached; 
    } 

    public object Disassemble(object value) 
    { 
     return value; 
    } 

    public SqlType[] SqlTypes 
    { 
     get { return new SqlType[] { new StringSqlType() }; } 
    } 

    public Type ReturnedType 
    { 
     get { return typeof(IList<string>); } 
    } 

    public bool IsMutable 
    { 
     get { return false; } 
    } 
} 

는 다음 유형 = "MyApp.DelimitedList, MyApp를"로 IList의 < 문자열 > 속성을 정의합니다.

참고 : SplitAndTrim은 제가 작성한 다양한 재정의가 적용된 문자열 확장입니다. 핵심 방법은 다음과 같습니다.

public static IList<string> SplitAndTrim(this string s, StringSplitOptions options, params string[] delimiters) 
    { 
     if (s == null) 
     { 
      return null; 
     } 
     var query = s.Split(delimiters, StringSplitOptions.None).Select(x => x.Trim()); 
     if (options == StringSplitOptions.RemoveEmptyEntries) 
     { 
      query = query.Where(x => x.Trim() != string.Empty); 
     } 
     return query.ToList(); 
    } 
7

당신은이 작업을 수행 할 수 있습니다

<bag name="Identities" access="property"> 
    <key column="accountId"/> 
    <element column="identity" type="string"/> 
</bag> 

신원은 거기에 IList<string>

관련 문제