nhibernate中的集合级联类型
我正在使用 NHibernate 3.2,并使用代码映射。
测试用例非常简单 - 我有一个商店和一个产品,通过多对多集合链接。 StoreMap 中的多对多集合映射如下:
Set(x => x.Products, x =>
{
x.Fetch(CollectionFetchMode.Subselect);
x.Key(key =>
{
key.Column("StoreId");
key.ForeignKey("FK_StoreProducts_Store");
});
x.Table("StoreProducts");
x.Cascade(Cascade.None);
x.Inverse(true);
},
如果我是正确的,级联选项应该允许您选择是否要将类上的操作级联到集合。 NHibernate 3.2 允许这些选项,这对我来说并不是很简单:
[Flags]
public enum Cascade
{
None = 0,
Persist = 2,
Refresh = 4,
Merge = 8,
Remove = 16,
Detach = 32,
ReAttach = 64,
DeleteOrphans = 128,
All = 256,
}
我使用的示例是下面的示例,我在其中创建一个测试 Store 和一个测试 Product,并将其分配给该 store。然后我重新加载商店,检索第一个产品,更新它并保存商店。
即使级联设置为“无”,产品仍然会更新!发生这种情况正常吗?
using (var session = SessionFactory.OpenSession())
{
long storeId = 5;
using (var t = session.BeginTransaction())
{
Product p1 = new Product();
p1.Name = "Product 1";
session.Save(p1);
Store store = new Store();
store.Name = "Tesco";
session.Save(store);
p1.Stores.Add(store);
store.Products.Add(p1);
session.Save(store);
storeId = store.Id;
t.Commit();
}
using (var t = session.BeginTransaction())
{
Store s = session.Get<Store>(storeId);
Product p = s.Products.FirstOrDefault();
p.Name = "Product 1 Updated";
session.Save(s);
t.Commit(); // <-- Product is still being updated here!
}
session.Flush();
}
I am using NHibernate 3.2, and using Mapping by Code.
The test case is pretty straight-forward - I have a Store and a Product, linked by a many-to-many collection. The many-to-many collection in the StoreMap is mapped as follows:
Set(x => x.Products, x =>
{
x.Fetch(CollectionFetchMode.Subselect);
x.Key(key =>
{
key.Column("StoreId");
key.ForeignKey("FK_StoreProducts_Store");
});
x.Table("StoreProducts");
x.Cascade(Cascade.None);
x.Inverse(true);
},
If I am correct, the Cascade option should allow you to choose whether you want to cascade operations on the class, to the collection as well. NHibernate 3.2 allows these options, which are not really straightforward for me:
[Flags]
public enum Cascade
{
None = 0,
Persist = 2,
Refresh = 4,
Merge = 8,
Remove = 16,
Detach = 32,
ReAttach = 64,
DeleteOrphans = 128,
All = 256,
}
The example I am using is the one below, where I am creating a test Store, and a test Product, and assigning it to the store. Then I am reloading the Store, retrieving the first Product, updating it, and saving the Store.
Even though the cascade is set as 'None', the Product still updates! Is it normal that this should happen?
using (var session = SessionFactory.OpenSession())
{
long storeId = 5;
using (var t = session.BeginTransaction())
{
Product p1 = new Product();
p1.Name = "Product 1";
session.Save(p1);
Store store = new Store();
store.Name = "Tesco";
session.Save(store);
p1.Stores.Add(store);
store.Products.Add(p1);
session.Save(store);
storeId = store.Id;
t.Commit();
}
using (var t = session.BeginTransaction())
{
Store s = session.Get<Store>(storeId);
Product p = s.Products.FirstOrDefault();
p.Name = "Product 1 Updated";
session.Save(s);
t.Commit(); // <-- Product is still being updated here!
}
session.Flush();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您面临的功能称为 更改跟踪,与级联选项无关。 NHibernate 跟踪与会话关联的所有对象,并在事务提交时将所有更改发送到数据库。
如果你不需要它,你可以使用 无状态会话,以便获取非跟踪实体。但在这种情况下,您将不会有延迟加载。您还可以尝试使用
FlushMode.Never
来防止 NHibernate 自动刷新对数据库的更改Feature that you are facing is called change tracking, and has nothing to do with cascading options. NHibernate tracks all objects that are associated with a session and sends all changes to DB when transaction is committed.
If you don't need it you can use Stateless session in order to get non tracked entities. But in this case you will not have lazy loading. Also you can try to use
FlushMode.Never
in order to prevent NHibernate from automatic flushing changes to DB