连贯NHibernate多对多额外列不插 [英] Fluent NHibernate Many to Many with extra column does not insert
问题描述
我用流利的NHibernate的挣扎从流利NHibernate的许多一对多额外列
I'm struggling with fluent nhibernate from Fluent Nhibernate Many-to-Many mapping with extra column
我已经复制的映射,并写入最小的程序,我可以......但它不会救...会有人能提供一些见解?
I've copied the mappings and written the smallest program I can... but it wont save... Would anybody be able to provide some insight ???
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public IList<Inventory> Inventory { get; set; }
public Product()
{
Inventory = new List<Inventory>();
}
}
public class Warehouse
{
public int Id { get; set; }
public string Name { get; set; }
public IList<Inventory> Inventory { get; set; }
public Warehouse()
{
Inventory = new List<Inventory>();
}
}
public class Inventory
{
public Product Product { get; set; }
public Warehouse Warehouse { get; set; }
public bool StockInHand { get; set; }
// override object.Equals
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var i = obj as Inventory;
return ((i.Product.Id == this.Product.Id)
&& (i.Warehouse.Id == this.Warehouse.Id));
}
// override object.GetHashCode
public override int GetHashCode()
{
return 9999;
}
}
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
Not.LazyLoad();
Table("Product");
Id(x => x.Id).GeneratedBy.Assigned();
Map(x => x.Name);
HasMany(x => x.Inventory).AsBag()
.Cascade.All()
//.Inverse()
.Table("Inventory");
}
}
public class WarehouseMap : ClassMap<Warehouse>
{
public WarehouseMap()
{
Not.LazyLoad();
Table("Warehouse");
Id(x => x.Id).GeneratedBy.Assigned();
Map(x => x.Name);
HasMany(x => x.Inventory).AsBag()
.Cascade.All()
.Inverse()
.Table("Inventory");
}
}
public class InventoryMap : ClassMap<Inventory>
{
public InventoryMap()
{
Not.LazyLoad();
Table("Inventory");
CompositeId()
.KeyReference(x => x.Product, "Product_id")
.KeyReference(x => x.Warehouse, "Warehouse_id");
Map(x => x.StockInHand);
}
}
和程序...
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
Product p = new Product() { Id = 1, Name="product" };
Inventory i = new Inventory() { StockInHand = true };
i.Product = p;
p.Inventory.Add(i);
Warehouse w = new Warehouse() { Id = 1, Name = "warehouse" };
i.Warehouse = w;
w.Inventory.Add(i);
session.SaveOrUpdate(p);
session.Flush();
transaction.Commit();
}
}
我得到的例外是
The exception I get is
constraint failed\r\nforeign key constraint failed
我也输出创建语句,这看起来是正确的,我...
I've also output the create statements, which look correct to me...
create table Inventory (
Product_id INT not null,
Warehouse_id INT not null,
StockInHand BOOL,
primary key (Product_id, Warehouse_id),
constraint FK2B4C61665C5B845 foreign key (Product_id) references Product,
constraint FK2B4C616A6DE7382 foreign key (Warehouse_id) references Warehouse)
create table Product (
Id INT not null,
Name TEXT,
primary key (Id)
)
create table Warehouse (
Id INT not null,
Name TEXT,
primary key (Id)
)
和被之前的异常运行SQL ....
And the SQL that is run prior to the exception....
NHibernate:
INSERT
INTO
Warehouse
(Name, Id)
VALUES
(@p0, @p1);
@p0 = 'warehouse' [Type: String (0)], @p1 = 1 [Type: Int32 (0)]
NHibernate:
INSERT
INTO
Inventory
(StockInHand, Product_id, Warehouse_id)
VALUES
(@p0, @p1, @p2);
@p0 = True [Type: Boolean (0)], @p1 = 1 [Type: Int32 (0)], @p2 = 1 [Type: Int32 (0)]
那么这是怎么应该正常工作?!?
So how is this supposed to work correctly?!?
推荐答案
你的问题的原因是,NHibernate的尝试插入广告资源
的仓库前纪录
记录。这是因为插入的顺序是由在 session.Save
被调用的顺序控制。基于此信息,我尝试了一些代码的变化,这将防止外键约束的错误。我已经发布下面我最好的解决方案。
The cause of your issue is that NHibernate is trying to insert the Inventory
record before the Warehouse
record. This is because the order of insertions is governed by the order in which session.Save
is called. Based on this information I tried a number of code variations that will prevent the Foreign Key Constraint error. I have posted my nicest solution below.
using (var session = sessionFactory.OpenSession())
using (var transaction = session.BeginTransaction())
{
var warehouse = new Warehouse() { Id = 1, Name = "warehouse" };
session.Save(warehouse);
var product = new Product() {Id = 1, Name = "product"};
var inventory = new Inventory
{ StockInHand = true, Product = product, Warehouse = warehouse};
product.Inventory.Add(inventory);
warehouse.Inventory.Add(inventory);
session.Save(product);
transaction.Commit();
}
有一件事,我发现,这让我吃惊不少,就是如果你把 session.Save(仓库)
在 warehouse.Inventory.Add(库存)
然后NHibernate的不插仓库
记录第一和外键引发错误。
One thing I discovered, which surprised me quite a bit, is that if you put the session.Save(warehouse)
after warehouse.Inventory.Add(inventory)
then NHibernate doesn't insert the Warehouse
record first and the Foreign Key error is thrown.
最后一点,以获得三个插入语句下面所列的逆()
已被重新设置在 ProductMap
映射类。否则,额外的更新语句将被NHibernate的发出。
As a final note, to obtain the three insert statements as listed below the Inverse()
has to be re-instated in the ProductMap
mapping class. Otherwise an additional update statement will be emitted by NHibernate.
INSERT INTO Warehouse (Name, Id) VALUES (@p0, @p1);@p0 = 'warehouse'
[Type: String (4000)], @p1 = 1 [Type: Int32 (0)]
INSERT INTO Product (Name, Id) VALUES (@p0, @p1);
@p0 = 'product' [Type: String (4000)], @p1 = 1 [Type: Int32 (0)]
INSERT INTO Inventory (StockInHand, Product_id, Warehouse_id) VALUES (@p0, @p1, @p2);
@p0 = True [Type: Boolean (0)], @p1 = 1 [Type: Int32 (0)], @p2 = 1 [Type: Int32 (0)]
这篇关于连贯NHibernate多对多额外列不插的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!