NHibernate错误信息: 对象引用了未保存的瞬时实例 - 在刷新之前保存瞬时实例。

4
我正在使用nHibernate并尝试添加一些主从数据。数据库图表在此处附上。 Database diagram 以下是添加类别及两个产品的代码:
//Category
namespace Sample.CustomerService.Domain
{

    public class Category {
        public Category() {
            Products = new List<Product>();
        }
        public virtual int CategoryID { get; set; }
        public virtual IList<Product> Products { get; set; }
        public virtual string Name { get; set; }
        public virtual string Unit { get; set; }

        public virtual void AddProduct(Product product)
        {
            Products.Add(product);
        }
    }
}

//CategoryMap
namespace Sample.CustomerService.Domain
{

    public class CategoryMap : ClassMap<Category> {

        public CategoryMap() {
            Table("Category");
            LazyLoad();
            Id(x => x.CategoryID).GeneratedBy.Identity().Column("CategoryID");
            Map(x => x.Name).Column("Name").Not.Nullable().Length(50);
            Map(x => x.Unit).Column("Unit").Not.Nullable().Length(3);
            HasMany(x => x.Products).KeyColumn("CategoryID");
        }
    }
}

//--------------------------------------------------------------------------------------------
//Product
namespace Sample.CustomerService.Domain
{

    public class Product {
        public Product() {
        }
        public virtual int ProductID { get; set; }
        public virtual Category Category { get; set; }
        public virtual string Name { get; set; }
        public virtual decimal UnitPrice { get; set; }

    }
}

//ProductMap
namespace Sample.CustomerService.Domain {


    public class ProductMap : ClassMap<Product> {

        public ProductMap() {
            Table("Product");
            LazyLoad();
            Id(x => x.ProductID).GeneratedBy.Identity().Column("ProductID");
            References(x => x.Category).Column("CategoryID");
            Map(x => x.Name).Column("Name").Not.Nullable().Length(50);
            Map(x => x.UnitPrice).Column("UnitPrice").Not.Nullable();
        }
    }
}

//----------------------------------------------------------------------------------------------
//Program
namespace WindowsHibernateTest
{
    public partial class TestClass : Form
    {
        public TestClass()
        {
            InitializeComponent();
            CreateNewProduct();
        }

        public void CreateNewProduct()
        {
            try
            {
                var sessionFactory = CreateSessionFactory();
                using (var session = sessionFactory.OpenSession())
                {
                    using (var sqlTrans = session.BeginTransaction())
                    {
                        Category newGold = new Category() { Name = "Gold", Unit = "GRM" };

                        Product ngOrn = new Product() { Name = "Bangles", UnitPrice = 1000.10M };
                        Product ogOrn = new Product() { Name = "Rings", UnitPrice = 2000.10M };

                        AddProductsToCategory(newGold, ngOrn, ogOrn);

                        session.SaveOrUpdate(newGold);

                        sqlTrans.Commit();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private static ISessionFactory CreateSessionFactory()
        {
            return Fluently.Configure().Database(MsSqlConfiguration.MsSql2005.
                ConnectionString("Data Source=MyDB; Initial Catalog=NHibernateTest; Trusted_Connection=true;")).Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>()).BuildSessionFactory();

        }

        public static void AddProductsToCategory(Category category, params Product[] products)
        {
            foreach (var product in products)
            {
                category.AddProduct(product);
            }
        }

    }
}

sqlTrans.Commit()这一行中,我得到了以下错误信息:

对象引用未保存的瞬态实例——在执行flush操作之前请先保存该瞬态实例。类型:Sample.CustomerService.Domain.Product,实体:Sample.CustomerService.Domain.Product

我已经搜索了相当长的时间,但没有找到令人信服的解决方案。我尝试过这个这个这个,但无法解决此错误。请帮助我解决这个错误。提前感谢您的帮助。

不知道那是否是你的问题,但你需要改变你那里的添加产品方法:foreach (var product in products) { category.AddProduct(product); product.Category = category; } - gdoron
1个回答

5

我认为在保存类别之前需要先保存产品,因为HasMany没有级联。另外,您需要更改添加产品的方法以保持关系。

foreach (var product in products)
{
    category.AddProduct(product); 
    product.Category = category;
} 

产品是类别的子级。没有类别,便无法创建产品。 - Nagesh
@Nagesh 为什么呢?你可以在它为空的时候保存它,但是你需要按照我评论中所说的更改关系,并将其添加到我的答案中。 - gdoron
顺便说一下,我认为你需要了解反向和级联的含义。这是我学习NH时的问题...祝你好运! - gdoron
请提供一些链接,让我可以下载有关Hibernate的文档。 - Nagesh
一个朋友发布的教程:http://www.codecovered.net/2011/04/nhibernate-tutorial-part-1-introduction.html - gdoron
嗨@gdoron,我在nHibernate中实现复合键表时遇到了困难。这是链接https://dev59.com/Wl3Ua4cB1Zd3GeqP8wx6 请帮助我解决这个问题。 - Nagesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接