2010-03-21 33 views
7

Tôi đang tìm cách duy trì tùy chọn người dùng thành tập hợp các cặp giá trị tên, trong đó giá trị có thể là int, bool hoặc chuỗi.Làm thế nào để ánh xạ IDictionary <string, object> trong Fluent NHibernate?

Có một vài cách để da mèo này, nhưng phương pháp thuận tiện nhất mà tôi có thể nghĩ đến là một cái gì đó như thế này:

public class User 
{ 
    public virtual IDictionary<string, object> Preferences { get; set; } 
} 

với việc sử dụng của nó như:

user.Preferences["preference1"] = "some value"; 
user.Preferences["preference2"] = 10; 
user.Preferences["preference3"] = true; 

var pref = (int)user.Preferences["preference2"]; 

Tôi không chắc chắn làm thế nào để bản đồ này trong Fluent NHibernate, mặc dù tôi nghĩ rằng đó là có thể.

Nói chung, bạn sẽ ánh xạ một đơn giản từ điển < string, string > như:

HasMany(x => x.Preferences) 
    .Table("Preferences") 
    .AsMap("preferenceName") 
    .Element("preferenceValue"); 

Nhưng với một loại 'đối tượng', NHibernate không biết làm thế nào để đối phó với nó. Tôi tưởng tượng một UserType tùy chỉnh có thể được tạo ra mà phá vỡ một 'đối tượng' xuống đến một chuỗi đại diện cho loại của nó và một chuỗi đại diện cho giá trị. Chúng tôi sẽ có một bảng trông loại như thế này:

Table Preferences 
    userId (int) 
    preferenceName (varchar) 
    preferenceValue (varchar) 
    preferenceValueType (varchar) 

và lập bản đồ ngủ đông sẽ như thế này:

<map name="Preferences" table="Preferences"> 
    <key column="userId"></key> 
    <index column="preferenceName" type="String" /> 
    <element type="ObjectAsStringUserType, Assembly"> 
    <column name="preferenceValue" /> 
    <column name="preferenceValueType"/> 
    </element> 
</map> 

Tôi không chắc chắn làm thế nào bạn sẽ lập bản đồ này trong thành thạo NHibernate.

Có thể có cách tốt hơn để làm điều này, hoặc có lẽ tôi chỉ nên hút nó lên và sử dụng IDictionary < chuỗi, chuỗi >. Bất kỳ ý tưởng?

+0

Bạn có tìm thấy giải pháp không? –

+0

Cảm ơn, chỉ những gì tôi đang tìm kiếm – jolySoft

Trả lời

6

tôi có thể nói IDictionary<string,string> sẽ dễ dàng hơn nhiều. Tuy nhiên, đây là mã số

 HasMany(u => u.Preferences) 
      .Table("Preferences") 
      .AsMap("preferenceName") 
      .Element("preferenceType", e => e.Column("preferenceValue").Type<ObjAsStringUserType>()); 

class ObjAsStringUserType : ImmutableUserType 
{ 
    public override object NullSafeGet(IDataReader rs, string[] names, object owner) 
    { 
     var type = (string)NHibernateUtil.String.NullSafeGet(rs, names[0]); 
     var value = (string)NHibernateUtil.String.NullSafeGet(rs, names[1]); 

     switch (type) 
     { 
      case "boolean": 
       return bool.Parse(value); 
       ... 
      default: 
       return null; 
       break; 
     } 
    } 

    public override void NullSafeSet(IDbCommand cmd, object value, int index) 
    { 
     var type = value.GetType().Name; 
     var valuestring = value.ToString(CultureInfo.InvariantCulture); 

     NHibernateUtil.String.NullSafeSet(cmd, type, index); 
     NHibernateUtil.String.NullSafeSet(cmd, valuestring, index + 1); 
    } 

    public override Type ReturnedType 
    { 
     get { return typeof(object); } 
    } 

    public override SqlType[] SqlTypes 
    { 
     get { return new [] 
     { 
      SqlTypeFactory.GetString(length: 255), // preferenceType 
      SqlTypeFactory.GetString(length: 255), // preferenceValue 
     }; 
     } 
    } 
} 
+0

Cảm ơn bạn đã giúp đỡ fella, tại chỗ trên – jolySoft

+0

ImmutableUserType là gì? Tôi không thể tìm thấy một tham chiếu đến nó trong NHibernate hoặc FNH. –

+0

@ JeffDoolittle nó là basetype của tôi thực hiện NH's IUseryType. tôi đã đăng nó ở đây http://stackoverflow.com/a/7484139/671619 – Firo

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