2010-06-02 50 views
2

我收到以下异常。NHibernate.PropertyValueException:非空属性引用空或瞬态

NHibernate.PropertyValueException:非空属性引用null或瞬时

这里是我的映射文件。

产品

<class name="Product" table="Products"> 
    <id name="Id" type="Int32" column="Id" unsaved-value="0"> 
     <generator class="identity"/> 
    </id> 
    <set name="PriceBreaks" table="PriceBreaks" generic="true" cascade="all" inverse="true" > 
     <key column="ProductId" /> 
     <one-to-many class="EStore.Domain.Model.PriceBreak, EStore.Domain" /> 
    </set>  

    </class> 

价格休息

<class name="PriceBreak" table="PriceBreaks"> 
    <id name="Id" type="Int32" column="Id" unsaved-value="0"> 
     <generator class="identity"/> 
    </id> 
    <property name="ProductId" column="ProductId" type="Int32" not-null="true" /> 

    <many-to-one name="Product" column="ProductId" not-null="true" cascade="all" class="EStore.Domain.Model.Product, EStore.Domain" /> 

    </class> 

我得到下面的方法

[Test] 
public void Can_Add_Price_Break() 
{ 

    IPriceBreakRepository repo = new PriceBreakRepository(); 

    var priceBreak = new PriceBreak(); 

    priceBreak.ProductId = 19; 
    repo.Add(priceBreak); 

    Assert.Greater(priceBreak.Id, 0); 
} 

上一月的答复跟进例外。我已经从priceBreak地图中删除了ProductId。这工作!

public int AddPriceBreak(Product product, PriceBreak priceBreak) 
    { 


     using (ISession session = EStore.Domain.Helpers.NHibernateHelper.OpenSession()) 
     using (ITransaction transaction = session.BeginTransaction()) 
     { 

      product.AddPriceBreak(priceBreak); 
      session.SaveOrUpdate(product); 
      transaction.Commit(); 
     } 

     return priceBreak.Id; 
    } 

回答

2

从映射和PriceBreak类中删除ProductId属性。并且使用PriceBreaks集合来添加PriceBreaks,您不需要PriceBreakRepository,而只需要一个ProductRepository。

例子:

using (var session = sessionFactory.OpenSession()) 
{ 
    using (var tx = session.BeginTransaction()) 
    { 

    var product = session.Get<Product>(19); 
    product.AddPriceBreak(new PriceBreak()); 

    tx.Commit(); 
    } 
} 

和产品:

class Product 
{ 
    // ... 
    public void AddPriceBreak(PriceBreak pb) 
    { 
    pb.Product = this; 
    PriceBreaks.Add(pb); 
    } 
} 
+0

感谢扬,试过,但它不是在传递产品ID。见上面的 – frosty 2010-06-03 09:32:49

+0

啊,被一些限制绊倒了。欢迎所有感谢 – frosty 2010-06-03 11:47:39

+0

欢迎:) – 2010-06-03 20:23:31

1

您对Id属性以及实际引用的使用是错误的。

首先,删除此行:

<property name="ProductId" column="ProductId" type="Int32" not-null="true" /> 

然后,而不是分配ProductId(你应该完全删除该属性),用途:

priceBreak.Product = session.Load<Product>(19); 

(您可能需要添加Load方法到您的存储库)。

相关问题