2011-10-13 30 views
7

Hãy cho tôi biết đây có phải là cách tiếp cận tốt để xóa một thực thể mà không tìm nạp nó khi có ID.Mã khuôn khổ thực thể đầu tiên xóa theo ID mà không tìm nạp (Kiểu chung)

tôi có một cửa hàng chung với giao diện như sau (tôi sẽ chỉ hiển thị Xoá):

public interface IStore : IReadOnlyStore 
{ 
    void Delete<TEntity>(TEntity entity) where TEntity : class, IEntity, new(); 
    void SaveChanges(); 
} 

Và trong lớp cửa hàng cụ thể của giao diện đó, đây là phương pháp xóa của tôi:

public void Delete<TEntity>(TEntity entity) where TEntity : class, IEntity, new() 
{ 
    var obj = Ctx.Entry(entity); 
    if (obj.State == System.Data.EntityState.Detached) 
    { 
     Ctx.Set(typeof(TEntity)).Attach(obj.Entity); 
    } 
    Ctx.Set(typeof(TEntity)).Remove(obj.Entity); 
} 

Tôi đã thử nghiệm cả việc tạo mới một Thực thể:

Store.Delete(new Foo() { Id = request.Entity.Id }); 

cũng như tìm nạp thực thể và sau đó gọi ng xóa.

Thông qua gỡ lỗi, tôi có ảnh hưởng mong muốn trên cả hai trường hợp.

Tôi chỉ muốn đảm bảo đây là thiết kế tốt và không có tác dụng phụ nào đối với phương pháp này.

Để tham chiếu, Ctx chỉ là chính DbContext.

Cảm ơn.

Trả lời

3

Đó là thiết kế tốt và không có tác dụng phụ :) (IMHO)

Hai nhận xét:

  • Tôi đang tự hỏi nếu bạn có thể đơn giản hóa phương pháp Delete của bạn bằng cách:

    public void Delete<TEntity>(TEntity entity) 
        where TEntity : class, IEntity, new() 
    { 
        Ctx.Entry(entity).State = EntityState.Deleted; 
    } 
    

    Tôi hy vọng rằng việc đặt trạng thái thành Deleted sẽ tự động đính kèm nếu đối tượng chưa được đính kèm. Nhưng tôi không chắc chắn nếu nó hoạt động. (Hãy cho tôi biết liệu nó có hoạt động cho các kịch bản đính kèm và tách rời (nếu bạn nên kiểm tra điều này).)

  • Nếu bạn có ý tưởng tối ưu hóa hiệu suất (tránh tải các thực thể) đừng quên rằng, nếu có nhiều các đối tượng cần xóa trong ngữ cảnh, SaveChanges sẽ vẫn gửi một câu lệnh DELETE cho mỗi thực thể đến cơ sở dữ liệu. Xóa hàng loạt với EF là khá khủng khiếp trong hoạt động và nó là một địa hình nơi sẽ trở lại một câu lệnh SQL (DELETE ... WHERE ... IN ... nhiều ID ....) đôi khi có ý nghĩa (nếu hiệu suất vấn đề).

+0

Cảm ơn bạn đã phản hồi về yoru. Tôi đã thử đề xuất của bạn, nhưng nó đã giết hơn 50% các bài kiểm tra đơn vị của tôi. Lỗi phổ biến có vẻ là: Đã xảy ra lỗi trong khi lưu các đối tượng không hiển thị thuộc tính khóa ngoại cho mối quan hệ của chúng. Thuộc tính EntityEntries sẽ trả về null vì một thực thể đơn lẻ không thể được xác định là nguồn của ngoại lệ. Xử lý các ngoại lệ trong khi tiết kiệm có thể được thực hiện dễ dàng hơn bằng cách phơi bày các thuộc tính khóa ngoài trong các loại thực thể của bạn. – Forest

+0

Xem InnerException để biết chi tiết. ---> System.Data.UpdateException: Một mối quan hệ từ 'Foo_Siblings' AssociationSet đang ở trạng thái 'Đã xóa'. Với các ràng buộc bội số, một 'Foo_Siblings_Target' tương ứng cũng phải ở trạng thái 'Đã xóa'. – Forest

Các vấn đề liên quan