5

Tôi có mối quan hệ nhiều đến nhiều:Làm thế nào để xóa trong một mối quan hệ nhiều đến nhiều?

Sản phẩm có nhiều Danh mục và Danh mục có nhiều Sản phẩm.

Nói rằng tôi có

Shopping Category 
Food Category 

Product A - Shopping Category, Food Category 
Product B - Shopping Category 

Bây giờ tôi xóa Shopping Category. Tôi muốn tham chiếu Product A bị xóa khỏi Shopping Category và tôi muốn xóa Product B hoàn toàn.

tôi sẽ kết thúc với:

Product A - Food Category. 

Làm thế nào để làm điều này trong nhibernate (Tôi đang sử dụng nhibernate thông thạo).

Tôi đã cố gắng sử dụng Cascade DeleteOrphanAllDeleteOrphan nhưng khi tôi làm điều đó và xóa Mua sắm, cả Sản phẩm A và B đều bị xóa.

public class CategoryMapping : ClassMap<Category> 
{ 
    public CategoryMapping() 
    { 
     Id(x => x.Id).GeneratedBy.GuidComb(); 

     Map(x => x.Name).Not.Nullable().NvarcharWithMaxSize(); 
     HasManyToMany(x => x.Products).Cascade.DeleteOrphan(); 
    } 
} 


public class ProductMapping : ClassMap<Product> 
{ 
    public ProductMapping() 
    { 
     Id(x => x.Id).GeneratedBy.GuidComb(); 
     Map(x => x.Name).Not.Nullable().NvarcharWithMaxSize(); 
     HasManyToMany(x => x.Categories); 
    } 
} 

    unitOfWork.BeginTransaction(); 
    Category category =session.Load<Category>(id); 
    session.Delete(category); 
    unitOfWork.Commit(); 

Trả lời

2

Tôi không nghĩ rằng điều này có thể được xử lý bằng cách ánh xạ với cấu trúc dữ liệu hiện có. Tôi nghĩ rằng bạn sẽ cần phải viết một số mã thủ công (*) hoặc thay đổi cấu trúc dữ liệu.

(*) Không phải 100% chắc chắn nó hoạt động mặc dù ...

unitOfWork.BeginTransaction(); 
Category category =session.Load<Category>(id); 
var productsDel = category.Products.Where(p => p.Categories.Count == 1); 
productsDel.ForEach(p => session.Delete(p)); 
session.Delete(category); 
unitOfWork.Commit(); 

khác:

Tôi cũng đang nghĩ về việc thêm bản đồ cho các bảng chéo ref của bạn. Sau đó, bạn sẽ có thể cấu hình ánh xạ để nó sẽ chỉ xóa các bản ghi từ bảng cross-ref đó. Bạn sẽ cần phải xác minh nếu có sản phẩm không có tham chiếu và xóa chúng định kỳ. (một số mã làm sạch định kỳ, như chạy một số thủ tục được lưu trữ). Tôi biết giải pháp này có mùi xấu :) Hiện vẫn còn gây nên và các công cụ SQL Server ... không giải pháp tốt anyway, nhưng giải pháp.

0

Nếu bạn chỉ muốn loại bỏ hiệp hội giữa hai sử dụng Cascade.SaveUpdate()

Sau đó chỉ cần loại bỏ các thực thể từ bộ sưu tập và cam kết giao dịch nếu bạn đang sử dụng các giao dịch nếu không bạn sẽ cần phải làm một phiên .Flush

+0

Tôi không hiểu. Tôi nghĩ saveUpdate cũng sẽ resave nó và tôi không chắc chắn những gì bạn có nghĩa là bằng cách loại bỏ các thực thể từ bộ sưu tập. Tôi có thể có 1000 của các sản phẩm cần tham khảo của họ để được loại bỏ khi tôi xóa các catergory vì vậy điều này có vẻ là những gì một thác sẽ được cho sau đó tôi phải làm điều đó bản thân mình. – chobo2

+0

Tôi có thể đã hiểu sai câu hỏi của bạn nhưng tôi chắc chắn có thể thấy lý do tại sao 'DeleteOrphan' và' AllDeleteOrphan' xóa Sản phẩm A trong trường hợp này. 'SaveUpdate' sẽ chỉ xóa các liên kết (nhiều đến nhiều mục bảng ...' product_category') nhưng sẽ không xóa 'Sản phẩm A'. Đây là một cái gì đó bạn sẽ phải xử lý bằng tay khi sử dụng thiết lập thác này. Tôi không nghĩ rằng có một thác mà xử lý này (có thể là sai mặc dù). –

+0

Hmm Tôi sẽ phải thử nó nhưng tôi nghĩ rằng DeleteOrphan chính xác cho tình huống này. Tôi không thấy nó như tôi Sản phẩm A không phải là một đứa trẻ mồ côi vì nó vẫn có mối quan hệ với một cái gì đó. – chobo2