2009-03-03 38 views
13

Tôi có một lớp miền với thuộc tính IList<string> mà tôi muốn ánh xạ tới một bảng với một giá trị dữ liệu duy nhất (tức là nó có ID, ID khóa ngoài cho bảng thực thể miền và cột dữ liệu varchar).Ánh xạ tập hợp các chuỗi với NHibernate

tôi tiếp tục nhận được lỗi:

Association references unmapped class: System.String

Làm thế nào tôi có thể ánh xạ một bảng vào một tập hợp các chuỗi?

+0

Có không có gì sai với điều này. Bạn chỉ cần ánh xạ nó với một-nhiều, mà chỉ hoạt động cho danh sách các thực thể. Hãy nhìn vào derek và Frederiks anserwers. –

Trả lời

22

Tôi vừa gặp tình huống tương tự; và tôi thấy rằng thực sự có thể lập bản đồ một bộ sưu tập các chuỗi. Lưu ý rằng bạn sẽ phải ánh xạ những chuỗi đó dưới dạng đối tượng giá trị.

Đây là những gì tôi có:

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

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

Mapping:

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

Đến đây một lần nữa, đây là bản đồ FluentNHibernate tôi đã sử dụng dựa trên ánh xạ XML của bạn: mapping.HasMany (x => x.Synonyms) .AsBag(). Element ("ChapterCode", m => m.Type ()); – roryf

+0

Không nên HashedSet là HashShet? –

+0

@roryf bạn đang sử dụng một Túi, nơi nó phải là một Set. Mã đúng phải là: HasMany (x => x.Synonyms) .Table ("Từ đồng nghĩa"). AsSet(). Element ("ChapterCode", m => m.Type () .Not.Nullable()); –

1

Bạn có thể làm điều này với IUserType như vậy:

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; } 
    } 
} 

Sau đó, xác định IList < chuỗi tài sản as type = "MyApp.DelimitedList, MyApp" >.

LƯU Ý: SplitAndTrim là một phần mở rộng chuỗi với các phần ghi đè khác nhau mà tôi đã tạo. Đây là phương pháp cốt lõi:

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

Trừ khi tôi nhầm lẫn bạn có thể làm điều này:

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

sắc là một IList<string>

Các vấn đề liên quan