如何在NHibernate实体之间创建3向关系?

时间:2015-05-06 05:29:34

标签: c# nhibernate orm entity nhibernate-mapping

我有以下NHibernate实体类:

public class ProductPrice
{
    private long _id;
    private long _price; //Let's not get side-tracked by the type
    private Currency _currency;
}

//Just showing for completeness; the link beween ProductPrice and Currency
//is working correctly
public class Currency
{
    private long _id;
    private String _threeLetterCode; //INR, USD, GBP, OMR etc.
    private String _displayName;
    private IList<ProductPrice> _productPrices = new List<ProductPrice>();
}

public class Item
{
    private long _id;
    private String _name;
    private IList<ProductPrice> _prices = new List<ProductPrice>();
}

public class Customer
{
    private long _id;
    private String _name;
    private IList<ProductPrice> _prices = new List<ProductPrice>();

}

我想创建一个链接元组(Customer, Item, ProductPrice)的单独映射表,因为我们希望能够以不同的价格提供相同的商品 对不同的客户。 CurrencyProductPrice很简单 一对多的关系。

我不知道如何在.hbm.xml文件中映射它。

到目前为止,我(仅进行部分映射):

<class name="Item" table="Items">
  <id name="ID">
    <generator class="native" />
  </id>
  <property name="Name" />
  <bag name="Prices" table="PriceList" inverse="true" cascade="none" lazy="false">
    <key column="ItemID" />
    <many-to-many class="ProductPrice" column="PriceID" />
  </bag>
</class>

<class name="ProductPrice" table="ProductPrices" lazy="true">
  <id name="ID">
    <generator class="native" />
  </id>
  <property name="Price" />
  <many-to-one name="Currency" class="Currency" column="CurrencyID" />
</class>

这只映射(Item, ProductPrice),但即使这样也不会导致输入 在我创建新PriceList时保存在ProductPrice表格中,将其添加到 Currency Item,将其添加到新的Item,然后保存CurrencyPriceList

所以我的问题是:

  1. 我错过了什么?
    1. 我如何确保在ProductPrice表格中输入一个条目 创建Item,将其添加到Item并保存(Item, ProductPrice)
  2. 如何将此双向(Customer, Item, ProductPrice)映射扩展为三向 (Customer, Item, ProductPrice)映射?
  3. 我该怎么做才能在PriceList表中有多个相同的ProductPrice行(public class ProductPrice { private long _id; private long _price; //Let's not get side-tracked by the type private Currency _currency; private IList<Item> _items = new List<Item>(); } //Just showing for completeness; the link beween ProductPrice and Currency //is working correctly public class Currency { private long _id; private String _threeLetterCode; //INR, USD, GBP, OMR etc. private String _displayName; private IList<ProductPrice> _productPrices = new List<ProductPrice>(); } public class Item { private long _id; private String _name; private IList<ProductPrice> _prices = new List<ProductPrice>(); } public class Customer { private long _id; private String _name; private IList<ProductPrice> _prices = new List<ProductPrice>(); } 有效 日期(此处未显示)以便能够提供短期特价)?
  4. 第2版:

    我有以下NHibernate实体类:

    (Customer, Item,
    ProductPrice)

    我想创建一个链接元组Currency的单独映射表,因为我们希望能够以不同的价格提供相同的商品 对不同的客户。 ProductPrice<class name="Item" table="Items"> <id name="ID"> <generator class="native" /> </id> <property name="Name" /> <bag name="Prices" table="PriceList" inverse="true" cascade="save-update" lazy="false"> <key column="ItemID" /> <many-to-many class="ProductPrice" column="PriceID" /> </bag> </class> 很简单 一对多的关系。

    我不知道如何在.hbm.xml文件中映射它。

    到目前为止,我(仅进行部分映射):

    <class name="ProductPrice" table="ProductPrices" lazy="true">
      <id name="ID">
        <generator class="native" />
      </id>
      <property name="Price" />
      <many-to-one name="Currency" class="Currency" column="CurrencyID" />
      <bag name="Items" table="PriceList" >
        <key column="PriceID" />
        <many-to-many class="Item" column="ItemID" />
      </bag>
    </class>
    

    (Item, ProductPrice)

    这只映射PriceList,但即使这样也不会导致输入 在我创建新ProductPrice时保存在Currency表格中,将其添加到 Item Item,将其添加到新的Currency,然后保存PriceListProductPrice

    所以我的问题是:

    1. 我错过了什么?
      1. 我如何确保在Item表格中输入一个条目 创建Item,将其添加到(Item, ProductPrice)并保存(Customer, Item, ProductPrice)
    2. 如何将此双向(Customer, Item, ProductPrice)映射扩展为三向 PriceList映射?
    3. 我该怎么做才能在ProductPrice表中有多个相同的Item行(ProductPrice有效 日期(此处未显示)以便能够提供短期特价)?
    4. 更新1

      添加了ProductPrice.hbm.xmlPriceLink的列表并更新了public class PriceLink { protected virtual long ID { get; set; } public virtual Customer Cust { get; set; } public virtual Item Item { get; set; } public virtual ProductPrice ProdPrice { get; set; } }

      更新2

      解决这个问题的一种不太复杂的方法是定义一个实体<class name="PriceLink"> <id name="ID"> <generator class="native" /> </id> <many-to-one name="Cust" class="Customer" column="CustomerID" /> <many-to-one name="Item" class="Item" column="ItemID" /> <many-to-one name="ProdPrice" class="ProductPrice" column="ProductPriceID" /> </class> 像这样:

      PriceLink

      并将其映射为:

      Currency curr = new Currency { DisplayName = "XYZ Currency", ThreeLetterCode = "XYZ" };
      ProductPrice prodPrice = new ProductPrice { SalePrice = 10000, ValidFrom = DateTimeOffset.MinValue, ValidUpto = DateTimeOffset.MaxValue };
      Item item = new Item { Name = "Item 1"};
      //PriceLink pl = new PriceLink();
      using (ISession session = NHibernateHelper.OpenSession())
      {
          prodPrice.Currency = curr;
          curr.ProductPrices.Add(prodPrice);
          //pl.Item = item;
          //pl.ProdPrice = prodPrice;
          prodPrice.Items.Add(item);
          item.Prices.Add(prodPrice);
          session.Save(curr);
          session.Save(item);
          //session.Save(pl);
      }
      

      然而,通过这个解决方案,我失去了(我认为)NHibernate的所有力量 能够检索整个对象图。这个贫民区解决方案值得吗?

      更新3

      这就是我在单元中保存实体(在我尝试let之前)的方式 测试(是的,我意识到这是hack-y代码而我不使用事务):

      struct  EHSearch {
      var EHcategory : String = ""
      var EHname : String = ""
      }
      

1 个答案:

答案 0 :(得分:0)

考虑您想要访问数据存储的项目。换句话说,不要将所有项目绑在一起,而应考虑根聚合。

在描述的模型中,您可能只想考虑拥有货币类而没有货币对产品价格的引用。

这样的模型会变得有点简单,虽然用户故事可能首先以这种方式驱使你,不确定?

话虽如此,我不希望nhibernate能够如此强大地检索所有整个对象图,而是选择多个这些图。就像产品价格和其他用户故事一样,您可能希望将货币作为汇总根。