2009-09-07 2 views
0

Я работаю на MVC приложения с помощью NHibernate как ОРМ (ncommon рамочном)Удаления неиспользуемых дочерних записей с NHibernate

У меня есть родительские/дочерние объекты: Продукт, Поставщик & ProductVendors и один ко многим отношений между ними с Продукт, имеющий коллекцию ProductVendors Product.ProductVendors.

В настоящее время я извлекаю объект продукта и охотно загружаю детей и отправляю их по кабелю моему клиенту asp.net mvc.

Пользователь изменит список поставщиков и отправит обновленный продукт обратно. Я использую настраиваемое связующее устройство для создания модифицированного объекта Product. Я могу обновить продукт и вставить новые ProductVendors.

Моя проблема заключается в том, что разыменованные ProductVendors не удаляются каскадом при указании Product.ProductVendors.Clear() и вызова _productRepository.Save (product).

Проблема, кажется, связана с прикрепленным отсоединенным экземпляром. Вот мои картографические файлы:

Продукт

<?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 { класс ProductUpdateModelBinder общественности: DefaultModelBinder { частные чтения 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(); 
     } 
    } 

Going орехи здесь, как я почти есть очень красивое решение между MVC , пользовательские привязки моделей и nhibernate.Просто не увидев, что мои удаленные каскады. Любая помощь очень ценится.

Чев

ответ

0

Если вы хотите, чтобы ваши дочерние объекты были удалены, когда родитель будет удален вам необходимо установить

cascade="all-delete-orphan" 

вариант в отображении коллекции. Подробнее о вариантах каскадирования вы можете найти here

+0

Спасибо за ответ. Я не пытаюсь удалить родителя, только дочерние объекты. – 2009-09-07 14:27:59

0

Нужно вызвать метод слияния сеанса: ISession. Слияние (продукт)

Смежные вопросы