问题描述
引用是单向的。此实体的表(StoreProduct)实际上是一个具有以下字段的连接表:$ b $ ul
Store_id
所以我使用了一个化合物ID(store_id和($ product_id),ExtraBit只是一个字符串:
pre $ public $ StoreProduct
protected StoreProduct :this(null,null,null){}
public StoreProduct(Store c_Store,Product c_Product,String c_ExtraBit)
{
Store = c_Store;
Product = c_Product;
ExtraBit = c_ExtraBit;
}
public virtual int Product_id {get;组; }
public virtual int Store_id {get;组; }
public virtual Store Store {get;组; }
public virtual Product Product {get;组; }
public virtual String ExtraBit {get;组; }
$ b public override int GetHashCode()
{
return Store.GetHashCode()+ Product.GetHashCode();
}
public override bool Equals(object obj)
{
StoreProduct obj_StoreProduct;
obj_StoreProduct = obj as StoreProduct;
if(obj_StoreProduct == null)
{
return false;
if(obj_StoreProduct.Product!= this.Product&& obj_StoreProduct.Store!= this.Store)
{
return false;
}
返回true;
$ b b
和映射:
public class Order_DetailMap:ClassMap< StoreProduct>
{
public Order_DetailMap()
{
表(StoreProduct);
LazyLoad();
CompositeId().KeyProperty(x => x.Store_id).KeyProperty(x => x.Product_id);
引用(x => x.Store).ForeignKey(Store_id)。Cascade.All();
引用(x => x.Product).ForeignKey(Product_id)。Cascade.All();
Map(x => x.ExtraBit);
code
我尝试保存StoreProduct及其新创建的商店和产品。谁能帮忙?这里有一些输出:
未处理的异常:System.ArgumentOutOfRangeException:索引超出范围。
必须是非负数,小于集合的大小。
参数名称:index $ b $在System.ThrowHelper.ThrowArgumentOutOfRangeException()
在System.Data.SQLite.SQLiteParameterCollection.GetParameter(Int32索引)$ b $在System.Data.Common.DbParameterCollection .System.Collections.IList.get_Item
(Int32 index)$ b $在NHibernate.Type.Int32Type.Set(IDbCommand rs,Object value,Int32 index)in
d:\CSharp\NH \NH\\\
hibernate\src\NHibernate\Type\Int32Type.cs:第60行$ NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd,对象值,$ $ b $ 32索引)在d:\CSharp\NH\NH\\\
hibernate\src\NHibernate\Type\NullableType.cs:行
180
在NHibernate.Type.NullableType.NullSafeSet(IDbCommand st,Object value,Int3
2 index,ISessionImplementor session)在d:\CSharp\NH\NH\\\
hibernate\src\NHiberna
te\Type\NullableType.cs :行NHibernate.Type.ComponentType.NullSafe 139
Set(IDbCommand st,Object value,Int
32 begin,ISessionImplementor session)在d:\CSharp\NH\NH\\\
hibernate\src\NHibern
ate\Type\ ComponentType.cs:行221
在NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(对象ID,O
bject []字段,对象rowId,布尔值[] includeProperty,布尔值[] [] includeColu
mns,Int32表,IDbCommand语句,ISessionImplementor会话,Int32索引
)在d:\CSharp\NH\NH\\\
hibernate\src\NHibernate\Persister\Entity\AbstractEntityPe
rsister.cs:第2418行
编辑:感谢以下帮助,我似乎有一个体面的解决方案:
$ b 商店映射和类:
namespace compoundIDtest.Domain.Mappings
{
public class StoreMap:ClassMap< Store>
{
public StoreMap()
{
Id(x => x.Id).Column(Store_id);
Map(x => x.Name);
HasMany(x => x.Staff)
.Inverse()
.Cascade.All();
HasManyToMany(x => x.Products)
.Cascade.All()
.Table(StoreProduct);
$ b namespace compoundIDtest.Domain.Entities
{
public class Store
{
public virtual int Id {get;私人设置}
public virtual string Name {get;组; }
公共虚拟IList<产品>产品{get;组; }
公共虚拟IList<员工>工作人员{get;组; }
公共虚拟IList< StoreProduct> StoreProducts {get;组; }
$ b $ public Store()
{
Products = new List< Product>();
Staff = new List< Employee>();
public virtual void AddProduct(Product product)
{
product.StoresStockedIn.Add(this);
Products.Add(product);
}
public virtual void AddEmployee(Employee employee)
{
employee.Store = this;
Staff.Add(employee);
public override int GetHashCode()
{
return Name.GetHashCode();
public override bool Equals(object obj)
{
Store obj_Store;
obj_Store = obj作为商店;
if(obj_Store == null)
{
return false;
if(obj_Store.Name!= this.Name)
{
return false;
}
返回true;
}
$ b}
}
产品映射和类
namespace compoundIDtest.Domain。映射
{
public class ProductMap:ClassMap< Product>
{
public ProductMap()
{
Id(x => x.Id).Column(Product_id);
Map(x => x.Name);
Map(x => x.Price);
HasManyToMany(x => x.StoresStockedIn)
.Cascade.All()
.Inverse()
.Table(StoreProduct);
$ b namespace compoundIDtest.Domain.Entities
{
public class Product
{
public virtual int Id {get;私人设置}
public virtual string Name {get;组; }
public virtual double Price {get;组; }
公共虚拟IList< Store> StoresStockedIn {get;组; }
公共虚拟IList< StoreProduct> StoreProducts {get;组; }
public Product()
{
StoresStockedIn = new List< Store>();
StoreProducts =新列表< StoreProduct>();
$ b public override int GetHashCode()
{
return Name.GetHashCode();
public override bool Equals(object obj)
{
Product obj_Product;
obj_Product = obj as Product;
if(obj_Product == null)
{
return false;
if(obj_Product.Name!= this.Name)
{
return false;
}
返回true;
和StoreProduct
namespace compoundIDtest.Domain.Mappings
{
公共类Order_DetailMap:ClassMap< StoreProduct>
{
public Order_DetailMap()
{
表(StoreProduct);
LazyLoad();
CompositeId()。KeyReference(x => x.Store,Store_id)。KeyReference(x => x.Product,Product_id);
引用(x => x.Store,Store_id)。Not.Update()。Not.Insert()。Cascade.All();
引用(x => x.Product,Product_id)。Not.Update()。Not.Insert()。Cascade.All();
Map(x => x.ExtraBit);
$ b namespace compoundIDtest.Domain.Entities
{
public class StoreProduct
{
public StoreProduct(){}
public virtual Store Store {get;组; }
public virtual Product Product {get;组; }
public virtual String ExtraBit {get;组; }
$ b public override int GetHashCode()
{
$ b $ if(this.ExtraBit!= null)
{
return Store.GetHashCode ()+ Product.GetHashCode()+ ExtraBit.GetHashCode();
}
return Store.GetHashCode()+ Product.GetHashCode();
$ b public override bool Equals(object obj)
{
StoreProduct obj_StoreProduct;
obj_StoreProduct = obj as StoreProduct;
if(obj_StoreProduct == null)
{
return false;
if(obj_StoreProduct.Product!= this.Product&& obj_StoreProduct.Store!= this.Store&& obj_StoreProduct.ExtraBit!= this.ExtraBit)
{
返回false;
}
返回true;
$ b $ p $强>这里是一个应用程序的代码来测试以上内容:
using System;
使用System.IO;
使用compoundIDtest.Domain.Entities;
使用FluentNHibernate.Cfg;
使用FluentNHibernate.Cfg.Db;
使用NHibernate;
使用NHibernate.Cfg;
使用NHibernate.Tool.hbm2ddl;
使用FluentNHibernate.Conventions;
namespace compoundIDtest
{
class Program
{
private const string DbFile =firstProgram.db;
static void Main()
{
//创建我们的NHibernate会话工厂
var sessionFactory = CreateSessionFactory();
使用(var session = sessionFactory.OpenSession())
{
//使用(var transaction = session.BeginTransaction())$ b填充数据库
$ b {
//创建几个商店,每个商店都有一些产品和员工
var barginBasin = new Store {Name =Bargin Basin};
var superMart = new Store {Name =SuperMart};
var CornerShop = new Store {Name =Corner Shop};
var potatoes = new Product {Name =Potatoes,Price = 3.60};
var fish = new Product {Name =Fish,Price = 4.49};
var milk = new Product {Name =Milk,Price = 0.79};
var bread = new Product {Name =Bread,Price = 1.29};
var cheese = new Product {Name =Cheese,Price = 2.10};
var waffles = new Product {Name =Waffles,Price = 2.41};
var poison = new Product {Name =Poison,Price = 1.50};
var daisy = new Employee {FirstName =Daisy,LastName =Harrison};
var jack = new Employee {FirstName =Jack,LastName =Torrance};
var sue = new Employee {FirstName =Sue,LastName =Walkters};
var bill = new Employee {FirstName =Bill,LastName =Taft};
var joan = new Employee {FirstName =Joan,LastName =Pope};
var storeproduct = new StoreProduct {Store = CornerShop,Product = poison,ExtraBit =Extra Bit};
//session.SaveOrUpdate(CornerShop);
//session.SaveOrUpdate(poison);
session.Save(storeproduct);
//将商品添加到商店中,每个
商店中的商品都有一些交叉,因为商品关系是多对多
AddProductsToStore(barginBasin,土豆,鱼,牛奶,面包,奶酪);
AddProductsToStore(superMart,bread,cheese,waffles);
//将员工添加到商店,这种关系是一对多的,所以一个
//员工一次只能在一个商店工作
AddEmployeesToStore( barginBasin,daisy,jack,sue);
AddEmployeesToStore(superMart,bill,joan);
//保存两个商店,这通过级联
session.SaveOrUpdate(barginBasin);
session.SaveOrUpdate(superMart);
//session.SaveOrUpdate(CornerShop);
//session.SaveOrUpdate(poison);
//session.SaveOrUpdate(store product);
transaction.Commit();
$ b使用(var session = sessionFactory.OpenSession())
{
// retreive all stores and display them
using(var transaction = session.BeginTransaction())
{
var products = session.CreateCriteria(typeof(Product))
.List< Product>();
foreach(var product in products)
{
product.Price = 100;
session.SaveOrUpdate(product);
$ b var storeproducts = session.CreateCriteria(typeof(StoreProduct))。List< StoreProduct>();
foreach(StoreProduct storeproduct in storeproducts)
{
if(storeproduct.Store.Name ==SuperMart)
{
storeproduct.ExtraBit =谢谢,再来;
}
session.SaveOrUpdate(storeproduct);
transaction.Commit();
$ b Console.ReadKey();
private static ISessionFactory CreateSessionFactory()
{
return Fluentfully.Configure()
.Database(SQLiteConfiguration.Standard
.UsingFile (DbFile))
.Mappings(m =>
m.FluentMappings.AddFromAssemblyOf< Program>())
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory()
private static void BuildSchema(Configuration config)
{
//删除每次运行的现有数据库
if(File.Exists(DbFile ))
File.Delete(DbFile);
//这个NHibernate工具需要一个配置(映射信息在)
//并从中导出一个数据库模式
新的SchemaExport(config)
.Create (假,真);
private static void WriteStorePretty(Store store)
{
Console.WriteLine(store.Name);
Console.WriteLine(Products:);
foreach(var product in store.Products)
{
Console.WriteLine(+ product.Name);
}
Console.WriteLine(Staff:);
foreach(var storeStaff中的雇员)
{
Console.WriteLine(+ employee.FirstName ++ employee.LastName);
}
Console.WriteLine();
public static void AddProductsToStore(store store,params Product [] products)
{
foreach(var product in products)
{
store.AddProduct(product);
public static void AddEmployeesToStore(Store store,params Employee [] employees)
{
foreach(var employee in employees)
{
store.AddEmployee(employee);
$ b $ / code $ / pre
解决方案我有一个映射几乎完全相同,我最终映射它是这样的:
public class Order_DetailMap:ClassMap< StoreProduct>
{
public Order_DetailMap()
{
表(StoreProduct);
CompositeId()
.KeyReference(x => x.Store,Store_id)
.KeyReference(x => x.Product,Product_id);
Map(x => x.ExtraBit);
$ Store
和 Product
类我添加和删除方法使得这个中间类的创建几乎看不见。示例如下:
public class Store
{
public IList< StoreProduct> StoreProducts {get;组; }
//其他属性和构造函数
public virtual void AddProduct(Product productToAdd,string extraBit)
StoreProduct newStoreProduct = new StoreProduct ,productToAdd,extraBit);
storeProducts.Add(newStoreProduct);
$ b $ p
$ b除了上面的内容,在我的 Store
和 Product
类中设置了code> StoreProduct
Cascade.AllDeleteOrphan()
我从未能够映射 StoreProduct
这样,当它自己保存时,它会创建一个新的 Store
和一个新的 Product
>。我不得不像上面那样映射它。因此,在您实际创建关系之前,您的 Store
或 Product
将需要存在( StoreProduct
),这取决于你是从哪个方面创建新的 StoreProduct
。
编辑:
您也可以像这样映射以达到您想要的效果:
public class Order_DetailMap:ClassMap< StoreProduct>
{
public Order_DetailMap()
{
表(StoreProduct);
CompositeId()
.KeyReference(x => x.Store,Store_id)
.KeyReference(x => x.Product,Product_id);
引用(x => x.Store,Store_id)
.Not.Update()
.Not.Insert()
.Cascade.All ();
引用(x => x.Product,Product_id)
.Not.Update()
.Not.Insert()
.Cascade.All ();
Map(x => x.ExtraBit);
}
}
The references are unidirectional. The table (StoreProduct) for this entity is actually a join table that has these fields:
- Store_id
- Product_id
- ExtraBit
So I went with an entity having a compoundID (store_id and product_id) and the ExtraBit is just a string:
public class StoreProduct
{
protected StoreProduct():this(null,null,null){ }
public StoreProduct(Store c_Store, Product c_Product, String c_ExtraBit)
{
Store = c_Store;
Product = c_Product;
ExtraBit = c_ExtraBit;
}
public virtual int Product_id { get; set; }
public virtual int Store_id { get; set; }
public virtual Store Store { get; set; }
public virtual Product Product { get; set; }
public virtual String ExtraBit { get; set; }
public override int GetHashCode()
{
return Store.GetHashCode() + Product.GetHashCode();
}
public override bool Equals(object obj)
{
StoreProduct obj_StoreProduct;
obj_StoreProduct = obj as StoreProduct;
if (obj_StoreProduct == null)
{
return false;
}
if (obj_StoreProduct.Product != this.Product && obj_StoreProduct.Store != this.Store)
{
return false;
}
return true;
}
}
And the mapping:
public class Order_DetailMap : ClassMap<StoreProduct>
{
public Order_DetailMap()
{
Table("StoreProduct");
LazyLoad();
CompositeId().KeyProperty(x => x.Store_id).KeyProperty(x => x.Product_id);
References(x => x.Store).ForeignKey("Store_id").Cascade.All();
References(x => x.Product).ForeignKey("Product_id").Cascade.All();
Map(x => x.ExtraBit);
}
}
It doesn't work though, when I tried saving the StoreProduct and its newly created Store and product. Can anyone help? Here is some output:
Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range.
Must be non-negative and less than the size of the collection.
Parameter name: index
at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at System.Data.SQLite.SQLiteParameterCollection.GetParameter(Int32 index)
at System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item
(Int32 index)
at NHibernate.Type.Int32Type.Set(IDbCommand rs, Object value, Int32 index) in
d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\Int32Type.cs:line 60
at NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int
32 index) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\NullableType.cs:line
180
at NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int3
2 index, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHiberna
te\Type\NullableType.cs:line 139
at NHibernate.Type.ComponentType.NullSafeSet(IDbCommand st, Object value, Int
32 begin, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibern
ate\Type\ComponentType.cs:line 221
at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, O
bject[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColu
mns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index
) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPe
rsister.cs:line 2418
Edit: Thanks to the help bellow I seem to have a decent solution:
Store Mapping and Class:
namespace compoundIDtest.Domain.Mappings
{
public class StoreMap : ClassMap<Store>
{
public StoreMap()
{
Id(x => x.Id).Column("Store_id");
Map(x => x.Name);
HasMany(x => x.Staff)
.Inverse()
.Cascade.All();
HasManyToMany(x => x.Products)
.Cascade.All()
.Table("StoreProduct");
}
}
}
namespace compoundIDtest.Domain.Entities
{
public class Store
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual IList<Product> Products { get; set; }
public virtual IList<Employee> Staff { get; set; }
public virtual IList<StoreProduct> StoreProducts { get; set; }
public Store()
{
Products = new List<Product>();
Staff = new List<Employee>();
}
public virtual void AddProduct(Product product)
{
product.StoresStockedIn.Add(this);
Products.Add(product);
}
public virtual void AddEmployee(Employee employee)
{
employee.Store = this;
Staff.Add(employee);
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
public override bool Equals(object obj)
{
Store obj_Store;
obj_Store = obj as Store;
if (obj_Store == null)
{
return false;
}
if (obj_Store.Name != this.Name)
{
return false;
}
return true;
}
}
}
Product Mapping And Class
namespace compoundIDtest.Domain.Mappings
{
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
Id(x => x.Id).Column("Product_id");
Map(x => x.Name);
Map(x => x.Price);
HasManyToMany(x => x.StoresStockedIn)
.Cascade.All()
.Inverse()
.Table("StoreProduct");
}
}
}
namespace compoundIDtest.Domain.Entities
{
public class Product
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual double Price { get; set; }
public virtual IList<Store> StoresStockedIn { get; set; }
public virtual IList<StoreProduct> StoreProducts { get; set; }
public Product()
{
StoresStockedIn = new List<Store>();
StoreProducts = new List<StoreProduct>();
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
public override bool Equals(object obj)
{
Product obj_Product;
obj_Product = obj as Product;
if (obj_Product == null)
{
return false;
}
if (obj_Product.Name != this.Name)
{
return false;
}
return true;
}
}
}
And StoreProduct
namespace compoundIDtest.Domain.Mappings
{
public class Order_DetailMap : ClassMap<StoreProduct>
{
public Order_DetailMap()
{
Table("StoreProduct");
LazyLoad();
CompositeId().KeyReference(x => x.Store, "Store_id").KeyReference(x => x.Product, "Product_id");
References(x => x.Store, "Store_id").Not.Update().Not.Insert().Cascade.All();
References(x => x.Product, "Product_id").Not.Update().Not.Insert().Cascade.All();
Map(x => x.ExtraBit);
}
}
}
namespace compoundIDtest.Domain.Entities
{
public class StoreProduct
{
public StoreProduct(){}
public virtual Store Store { get; set; }
public virtual Product Product { get; set; }
public virtual String ExtraBit { get; set; }
public override int GetHashCode()
{
if (this.ExtraBit != null)
{
return Store.GetHashCode() + Product.GetHashCode() + ExtraBit.GetHashCode();
}
return Store.GetHashCode() + Product.GetHashCode();
}
public override bool Equals(object obj)
{
StoreProduct obj_StoreProduct;
obj_StoreProduct = obj as StoreProduct;
if (obj_StoreProduct == null)
{
return false;
}
if (obj_StoreProduct.Product != this.Product && obj_StoreProduct.Store != this.Store && obj_StoreProduct.ExtraBit != this.ExtraBit)
{
return false;
}
return true;
}
}
}
And here is code for an app to test the above:
using System;
using System.IO;
using compoundIDtest.Domain.Entities;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using FluentNHibernate.Conventions;
namespace compoundIDtest
{
class Program
{
private const string DbFile = "firstProgram.db";
static void Main()
{
// create our NHibernate session factory
var sessionFactory = CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
// populate the database
using (var transaction = session.BeginTransaction())
{
// create a couple of Stores each with some Products and Employees
var barginBasin = new Store { Name = "Bargin Basin" };
var superMart = new Store { Name = "SuperMart" };
var CornerShop = new Store { Name = "Corner Shop" };
var potatoes = new Product { Name = "Potatoes", Price = 3.60 };
var fish = new Product { Name = "Fish", Price = 4.49 };
var milk = new Product { Name = "Milk", Price = 0.79 };
var bread = new Product { Name = "Bread", Price = 1.29 };
var cheese = new Product { Name = "Cheese", Price = 2.10 };
var waffles = new Product { Name = "Waffles", Price = 2.41 };
var poison = new Product { Name = "Poison", Price = 1.50 };
var daisy = new Employee { FirstName = "Daisy", LastName = "Harrison" };
var jack = new Employee { FirstName = "Jack", LastName = "Torrance" };
var sue = new Employee { FirstName = "Sue", LastName = "Walkters" };
var bill = new Employee { FirstName = "Bill", LastName = "Taft" };
var joan = new Employee { FirstName = "Joan", LastName = "Pope" };
var storeproduct = new StoreProduct { Store = CornerShop, Product = poison, ExtraBit = "Extra Bit"};
//session.SaveOrUpdate(CornerShop);
//session.SaveOrUpdate(poison);
session.Save(storeproduct);
// add products to the stores, there's some crossover in the products in each
// store, because the store-product relationship is many-to-many
AddProductsToStore(barginBasin, potatoes, fish, milk, bread, cheese);
AddProductsToStore(superMart, bread, cheese, waffles);
// add employees to the stores, this relationship is a one-to-many, so one
// employee can only work at one store at a time
AddEmployeesToStore(barginBasin, daisy, jack, sue);
AddEmployeesToStore(superMart, bill, joan);
// save both stores, this saves everything else via cascading
session.SaveOrUpdate(barginBasin);
session.SaveOrUpdate(superMart);
//session.SaveOrUpdate(CornerShop);
//session.SaveOrUpdate(poison);
//session.SaveOrUpdate(storeproduct);
transaction.Commit();
}
}
using (var session = sessionFactory.OpenSession())
{
// retreive all stores and display them
using (var transaction = session.BeginTransaction())
{
var products = session.CreateCriteria(typeof(Product))
.List<Product>();
foreach (var product in products)
{
product.Price = 100;
session.SaveOrUpdate(product);
}
var storeproducts = session.CreateCriteria(typeof(StoreProduct)).List<StoreProduct>();
foreach (StoreProduct storeproduct in storeproducts)
{
if (storeproduct.Store.Name == "SuperMart")
{
storeproduct.ExtraBit = "Thank you, come again";
}
session.SaveOrUpdate(storeproduct);
}
transaction.Commit();
}
}
Console.ReadKey();
}
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(SQLiteConfiguration.Standard
.UsingFile(DbFile))
.Mappings(m =>
m.FluentMappings.AddFromAssemblyOf<Program>())
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
private static void BuildSchema(Configuration config)
{
// delete the existing db on each run
if (File.Exists(DbFile))
File.Delete(DbFile);
// this NHibernate tool takes a configuration (with mapping info in)
// and exports a database schema from it
new SchemaExport(config)
.Create(false, true);
}
private static void WriteStorePretty(Store store)
{
Console.WriteLine(store.Name);
Console.WriteLine(" Products:");
foreach (var product in store.Products)
{
Console.WriteLine(" " + product.Name);
}
Console.WriteLine(" Staff:");
foreach (var employee in store.Staff)
{
Console.WriteLine(" " + employee.FirstName + " " + employee.LastName);
}
Console.WriteLine();
}
public static void AddProductsToStore(Store store, params Product[] products)
{
foreach (var product in products)
{
store.AddProduct(product);
}
}
public static void AddEmployeesToStore(Store store, params Employee[] employees)
{
foreach (var employee in employees)
{
store.AddEmployee(employee);
}
}
}
}
解决方案 I had a mapping pretty much identical to this and the way I ended up mapping it was like this:
public class Order_DetailMap : ClassMap<StoreProduct>
{
public Order_DetailMap()
{
Table("StoreProduct");
CompositeId()
.KeyReference(x => x.Store, "Store_id")
.KeyReference(x => x.Product, "Product_id");
Map(x => x.ExtraBit);
}
}
Inside of my Store
and Product
classes I have add and remove methods that make the creation of this middle class almost invisible. Example below:
public class Store
{
public IList<StoreProduct> StoreProducts { get; set; }
//Other properties and Constructors
public virtual void AddProduct(Product productToAdd, string extraBit)
{
StoreProduct newStoreProduct = new StoreProduct(this, productToAdd, extraBit);
storeProducts.Add(newStoreProduct);
}
}
In addition to the above I had HasMany's to a StoreProduct
collection in my Store
and Product
classes that are set to Cascade.AllDeleteOrphan()
I was never able to be able to map the StoreProduct
such that when it was saved by itself it would create a new Store
and a new Product
. I had to eventually map it like the above. So your Store
or Product
will need to exist before you actually create the relationship (StoreProduct
) between them depending on which side you are creating your new StoreProduct
from.
Edit:
You may also be able to map it like this to achieve what you are wanting:
public class Order_DetailMap : ClassMap<StoreProduct>
{
public Order_DetailMap()
{
Table("StoreProduct");
CompositeId()
.KeyReference(x => x.Store, "Store_id")
.KeyReference(x => x.Product, "Product_id");
References(x => x.Store, "Store_id")
.Not.Update()
.Not.Insert()
.Cascade.All();
References(x => x.Product, "Product_id")
.Not.Update()
.Not.Insert()
.Cascade.All();
Map(x => x.ExtraBit);
}
}
这篇关于流利Nhibernate:试图用复合键创建实体,也是两个引用的关键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!