2017-02-09 2 views
0

나는 데이터베이스에 정수 값을 저장하고리스트에서 선택된 비트 값의 합계를 담고있는 필드를 가지고있다. 예를 들어 :비트 sum을 NHibernate의리스트에 매핑하는 법

VALUE DESCRIPTION 
----- ----------- 
    1 Option 1 
    2 Option 2 
    4 Option 3 
    8 Option 4 

는 이제 & 4 선택이 옵션을 가정 해 봅시다, 그래서 필드에 저장된 값은 내가 힘든 시간을 알아내는 데 문제 10

것 (그것도 가능하다면) 방법 hbm.xml 파일에서이를 나타냅니다.

Id, int 
Name, varchar(25) 

Product.cs을

제품 테이블 열

Id, int 
Name, varchar(25) 
Services, int 

서비스 테이블 열 : 여기

내가 할 노력하고있어의 일반적인 예입니다

public class Product 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual IList<Service> Services { get; set; } 
} 

Service.cs

public class Service 
{ 
    public virtual int Id { get; set; } // bit values: 1, 2, 4, 8, ... 
    public virtual string Name { get; set; } 
} 

Product.hbm.xml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="AppNS" namespace="AppNS"> 
    <class name="Product" table="Product"> 
     <id name="Id" column="Id" type="int"> 
      <generator class="native"/> 
     </id> 
     <property name="Name" column="Name" type="string"/> 
     <????? name="Services" column="Services" type="AppNS.Service"/> 
    </class> 
</hibernate-mapping> 

Service.hbm.xml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="AppNS" namespace="AppNS"> 
    <class name="Service" table="Service"> 
     <id name="Id" column="Id" type="int"> 
      <generator class="native"/> 
     </id> 
     <property name="Name" column="Name" type="string"/> 
    </class> 
</hibernate-mapping> 
,745,

<과 관련하여 도움이 필요합니까? > 부분은 Product.hbm.xml 파일에 있습니다.

--EDIT--

는 궁극적으로, 나는 다시 내 제품 모델을 얻을 수있는로드() 메서드를 호출 할 수 있어야합니다.

Configuration cfg = new Configuration(); 
... 
ISessionFactory sf = cfg.BuildSessionFactory(); 
using (ISession s = sf.OpenSession()) 
{ 
    Product product = s.Load<Product>(100); 
    foreach(Service service in product.Services) 
    { 
     Console.WriteLine(service.Name); 
    } 
} 

출력은 다음과 같습니다

Option 2 
Option 4 

답변

1

이러한 필드가 간단한 속성으로 매핑해야합니다. 엔티티는이 속성을 플래그 열거 형으로 입력해야합니다. 나는 당신이 그것을리스트로 직접 맵핑 할 수 있다고 생각하지 않는다.

매핑 된 열거 형에서 목록을 대신 계산할 수 있습니다.

[Flags] 
public enum EService 
{ 
    Option1 = 1, 
    Option2 = 2, 
    Option3 = 4, 
    Option4 = 8 
} 

public class Product 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual EService Services { get; set; } 

    // Coded here for simplicity, though you'd probably do not want such 
    // dependencies here. 
    public virtual List<Service> GetServicesEntities(ISession session) 
    { 
     var services = new List<Service>(); 
     foreach (EService s in Enum.GetValues(typeof(EService))) 
     { 
      if ((Services & s) != 0 && 
       // In case you predefine combinations of options in the enum, you need 
       // this to avoid having them in the list too. 
       IsPowerOfTwo((int)s)) 
      { 
       services.Add(
        // Not a n+1 perf trouble if you have lazy loading batching enabled. 
        session.Load<Service>(s)); 
      } 
     } 
     return services; 
    } 

    // Taken from http://stackoverflow.com/a/600306/1178314 
    private bool IsPowerOfTwo(int x) 
    { 
     return (x != 0) && ((x & (x - 1)) == 0); 
    } 
} 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="AppNS" namespace="AppNS"> 
    <class name="Product" table="Product"> 
     <id name="Id" column="Id"> 
      <generator class="native"/> 
     </id> 
     <property name="Name" /> 
     <property name="Services" /> 
    </class> 
</hibernate-mapping> 

은 (그런데 매핑을 단순화, NHibernate에 컬럼 이름이 지정되지 않은 경우 속성 이름과 동일하다고 가정하고, 개체에서 속성 유형을 유추합니다.)

0

해보십시오 XML을 LINQ

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string header = 
       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + 
       "<hibernate-mapping xmlns=\"urn:nhibernate-mapping-2.2\" assembly=\"AppNS\" namespace=\"AppNS\">" + 
       "</hibernate-mapping>"; 

      Product.products = new List<Product>() { 
       new Product() { Id = 100, Name = "Product", Services = new List<Service>() { 
        new Service() {Id = 1, Name = "Option 1"}, 
        new Service() {Id = 2, Name = "Option 2"}, 
        new Service() {Id = 4, Name = "Option 3"}, 
        new Service() {Id = 8, Name = "Option 4"} 
       }} 
      }; 

      XDocument serviceXml = XDocument.Parse(header); 

      XElement mapping = (XElement)serviceXml.FirstNode; 
      foreach(Product product in Product.products) 
      { 
       XElement newProduct = new XElement("class"); 
       mapping.Add(newProduct); 

       newProduct.Add(new object[] { 
        new XAttribute("name",product.Name), 
        new XAttribute("table","Product"), 
        new XElement("id", new object[] { 
         new XAttribute("name", product.Id), 
         new XAttribute("column", product.Id), 
         new XAttribute("type","int"), 
         new XElement("generator", new XAttribute("class","native")) 
        }), 
        new XElement("property", new object[] { 
         new XAttribute("name","Name"), 
         new XAttribute("column", "Name"), 
         new XAttribute("type","string") 
        }) 
       }); 
       XElement services = new XElement("class", new object[] { 
        new XAttribute("name", "Service"), 
        new XAttribute("table", "Service") 
       }); 
       newProduct.Add(services); 

       foreach (Service service in product.Services) 
       { 
        services.Add(new XElement("id", new object[] { 
         new XAttribute("name", service.Name), 
         new XAttribute("column", service.Id), 
         new XAttribute("type", "int"), 
         new XElement("generator", new XAttribute("class","native")) 
        })); 
       } 
      } 
     } 
    } 
    public class Product 
    { 
     public static List<Product> products = new List<Product>(); 
     public virtual int Id { get; set; } 
     public virtual string Name { get; set; } 
     public virtual IList<Service> Services { get; set; } 
    } 
    public class Service 
    { 
     public virtual int Id { get; set; } // bit values: 1, 2, 4, 8, ... 
     public virtual string Name { get; set; } 
    } 
} 
+0

내 목표는 ISession.Load() 메서드를 호출하여 데이터베이스에서 내 Product 개체를 반환 할 수있게하는 것입니다. 이 제품은 데이터베이스 필드의 정수 값을 기반으로 선택된 목록의 서비스 만 갖습니다. 나는 당신의 대답이 저를 어떻게 데려 갈 수 있는지 보지 못합니다. – DanHarrigan