【问题标题】:How to create a 3-way relationship between NHibernate entities?如何在 NHibernate 实体之间创建三向关系?
【发布时间】:2015-05-06 05:29:33
【问题描述】:

我有以下 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),但即使这样也不会导致进入 当我创建一个新的ProductPrice 时保存在PriceList 表中,将其添加到 一个Currency,将它添加到一个新的Item,然后保存ItemCurrency

所以我的问题是:

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

版本 2:

我有以下 NHibernate 实体类:

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>();

}

我想创建一个单独的映射表来链接元组(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="save-update" 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" />
  <bag name="Items" table="PriceList" >
    <key column="PriceID" />
    <many-to-many class="Item" column="ItemID" />
  </bag>
</class>

这仅映射(Item, ProductPrice),但即使这样也不会导致进入 当我创建一个新的ProductPrice 时,将其保存在PriceList 表中,将其添加到 一个Currency,添加到一个新的Item,然后保存ItemCurrency

所以我的问题是:

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

更新 1

Item 的列表添加到ProductPrice 并更新ProductPrice.hbm.xml

更新 2

解决这个问题的一种简单的方法是定义一个实体PriceLink 像这样:

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

并像这样映射它:

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

但是,有了这个解决方案,我失去了(我认为)NHibernate 的所有功能 检索整个对象图的能力。这种贫民区解决方案值得吗?

更新 3

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

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

【问题讨论】:

    标签: c# nhibernate orm entity nhibernate-mapping


    【解决方案1】:

    考虑您希望访问数据存储的项目。换句话说,与其将所有项目捆绑在一起,不如考虑根聚合。

    在所描述的模型中,您可能需要考虑仅使用货币类,而无需从货币对 productprices 的引用。

    虽然用户故事可能首先驱使您这样做,但模型会变得更简单一些,不确定吗?

    话虽如此,我不希望 nhibernate 如此强大来检索所有整个对象图,而是选择这些图中的多个。就像具有价格的产品和另一个用户故事一样,您可能希望将货币作为聚合根。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-14
      • 1970-01-01
      • 2013-07-01
      相关资源
      最近更新 更多