我正在使用nhibernate作为orm(ncommon框架)的mvc应用程序
我有父/子实体:产品,供应商& ProductVendors和它们之间的一对多关系,Product与ProductVendors集合Product.ProductVendors。
我目前正在检索一个Product对象并急切地加载这些子对象并将它们发送到我的asp.net mvc客户端。
然后,用户将修改供应商列表并重新发布更新的产品。我正在使用自定义模型绑定器来生成修改后的Product实体。我可以更新产品并插入新的ProductVendors。
我的问题是,在指定Product.ProductVendors.Clear()并调用_productRepository.Save(product)时,不会级联删除已取消引用的ProductVendors。
问题似乎是附加分离的实例。这是我的映射文件:
产品
<?xml version="1.0" encoding="utf-8" ?>
<id name="Id">
<generator class="guid.comb" />
</id>
<version name="LastModified"
unsaved-value="0"
column="LastModified"
/>
<property name="Name" type="String" length="250" />
ProductVendors
<?xml version="1.0" encoding="utf-8" ?>
<id name="Id">
<generator class="guid.comb" />
</id>
<version name="LastModified"
unsaved-value="0"
column="LastModified"
/>
<property name="Price" />
<many-to-one
name="Product"
class="Product"
column="ProductId"
lazy="false"
not-null="true"
/>
<many-to-one
name="Vendor"
class="Vendor"
column="VendorId"
lazy="false"
not-null="true"
/>
自定义模型Binder:
using System;
使用Test.Web.Mvc; 使用Test.Domain;
命名空间Spoked.MVC { public class ProductUpdateModelBinder:DefaultModelBinder { private readonly ProductSystem ProductSystem;
public ProductUpdateModelBinder(ProductSystem productSystem)
{
ProductSystem = productSystem;
}
protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var product = bindingContext.Model as Product;
if (product != null)
{
product.Category = ProductSystem.GetCategory(new Guid(bindingContext.ValueProvider["Category"].AttemptedValue));
product.Brand = ProductSystem.GetBrand(new Guid(bindingContext.ValueProvider["Brand"].AttemptedValue));
product.ProductVendors.Clear();
if (bindingContext.ValueProvider["ProductVendors"] != null)
{
string[] productVendorIds = bindingContext.ValueProvider["ProductVendors"].AttemptedValue.Split(',');
foreach (string id in productVendorIds)
{
product.AddProductVendor(ProductSystem.GetVendor(new Guid(id)), 90m);
}
}
}
}
}
}
控制器:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update(Product product)
{
using (var scope = new UnitOfWorkScope())
{
//product.ProductVendors.Clear();
_productRepository.Save(product);
scope.Commit();
}
using (new UnitOfWorkScope())
{
IList<Vendor> availableVendors = _productSystem.GetAvailableVendors(product);
productDetailEditViewModel = new ProductDetailEditViewModel(product,
_categoryRepository.Select(x => x).ToList(),
_brandRepository.Select(x => x).ToList(),
availableVendors);
}
return RedirectToAction("Edit", "Products", new {id = product.Id.ToString()});
}
以下测试确实通过了:
[Test]
[NUnit.Framework.Category("ProductTests")]
public void Can_Delete_Product_Vendors_By_Dereferencing()
{
Product product;
using(UnitOfWorkScope scope = new UnitOfWorkScope())
{
Console.Out.WriteLine("Selecting...");
product = _productRepository.First();
Console.Out.WriteLine("Adding Product Vendor...");
product.AddProductVendor(_vendorRepository.First(), 0m);
scope.Commit();
}
Console.Out.WriteLine("About to delete Product Vendors...");
using (UnitOfWorkScope scope = new UnitOfWorkScope())
{
Console.Out.WriteLine("Clearing Product Vendor...");
_productRepository.Save(product); // seems to be needed to attach entity to the persistance manager
product.ProductVendors.Clear();
scope.Commit();
}
}
坚持到底,因为我在mvc,自定义模型绑定器和nhibernate之间几乎有一个非常好的解决方案。只是没有看到我的删除级联。非常感谢任何帮助。
CHEV
答案 0 :(得分:0)
答案 1 :(得分:0)
需要调用会话的Merge方法:ISession。合并(产品)