5
public class Order 
{ 
public int Id {get;set;} 
[DisplayName("User")] 
public long UserId { get; set; } 
[ForeignKey("UserId")] 
public virtual User User { get; set; } 
public decimal Amount { get; set; } 
} 

Với IEnumurableKhi nào cần hiển thị IEnumerable thay vì ICollection?

public class User 
{ 
public int Id{get;set;} 
public virtual IEnumerable<Order> Orders { get; set; } 
} 

public User GetWithOrders() 
{ 
var myUser=UserRepository.GetByEmail("[email protected]"); 
myUser.Orders=OrderRepository.GetByUserId(myUser.Id); 
return myUser; 
} 

Với ICollection

public class User 
{ 
public int Id{get;set;} 
public virtual ICollection<Order> Orders { get; set; } 
} 

public User GetWithOrders() 
{ 
var myUser=UserRepository.GetByEmail("[email protected]"); 
return myUser; 
} 

Tôi không có tải lười biếng sử dụng IEnumerable cho một tài sản chuyển hướng. Do đó, tôi phải nhận được đơn đặt hàng cho người dùng này bằng một truy vấn khác.

Tôi có điều hướng với ICollection. Vì vậy, tôi có thể tiếp cận đơn đặt hàng từ người dùng. Điều này có vẻ mát mẻ. Nhưng sau đó tôi có thể thêm đơn đặt hàng mới cho người dùng trong Bộ điều khiển mà không cần sử dụng dịch vụ hoặc kho lưu trữ.

Đó là loại thao tác dữ liệu ở cấp bộ điều khiển. Đây có phải là hình mẫu không?

Trả lời

2

Nhưng [với ICollection] Tôi có thể thêm đơn đặt hàng mới trong Bộ điều khiển mà không sử dụng dịch vụ hoặc kho lưu trữ.

Bạn có nghĩa là bạn có thể làm điều này (giả sử có một viewmodel cho thêm một để một người sử dụng và một SaveChanges() nơi nào đó):

public class UserController 
{ 
    public ActionResult AddUserOrder(AddUserOrderModel addOrder) 
    { 
     User user = User.GetByEmail(addOrder.UserEmail);   
     user.Orders.Add(addOrder.Order); 
     User.SaveChanges(); 
    } 
} 

Và đặc biệt là bạn có thể làm user.Orders.Add(...), thì đó là một tác dụng phụ hiển thị các loại thực thể từ lớp dịch vụ hoặc kho lưu trữ của bạn.

Nếu bạn muốn tránh điều đó, bạn phải xác định và vạch trần một đối tượng kinh doanh có chứa các thành viên bạn muốn để lộ:

public class UserBLL 
{ 
    public int Id { get; private set; } 
    public IEnumerable<Order> Orders { get { return _orders.AsEnumerable(); } } 
    private IEnumerable<Order> _orders; 

    public UserBLL(User user) 
    { 
     Id = user.Id; 
     _orders = user.Orders;   
    } 

    public void AddOrder(Order order) 
    { 
     _orders.Add(order); 
    } 
} 
+0

Thứ nhất, tôi cũng nghĩ viewmodel. Nhưng tôi không chắc nó có thể mang lại sự phức tạp hơn hay không. Tôi sẽ sử dụng chế độ xem nếu tôi phải. Cảm ơn. –

+0

Điểm không phải là chế độ xem, thực sự. Đó là BLL hoặc Mô hình miền. Một đối tượng đại diện cho trường hợp sử dụng của bạn (Người dùng có thể có Đơn đặt hàng). Sử dụng điều đó nếu bạn không muốn để lộ mô hình dữ liệu của bạn với tiếp xúc bên trong của họ. – CodeCaster

+0

Tại sao bạn trả về '_orders.AsEnumerable();' trong khi '_orders' đã là 'IEnumerable '? –

1

Không có lựa chọn thực sự ở đây. ICollection là cần thiết bởi EF để kiểm soát một số khía cạnh của nó như kết quả truy vấn ràng buộc và tải chậm. Bằng cách sử dụng IEnumerable, về cơ bản bạn đang tắt tất cả chức năng này, nhưng cùng với nó, sự hiểu biết của EF về cấu trúc cơ bản của bạn. Khi bạn tạo di chuyển, EF sẽ không tạo bất kỳ bảng tham chiếu cơ sở cần thiết nào cho các mối quan hệ M2M, các khóa ngoại trên các bảng có liên quan, v.v.

Dài và ngắn, sử dụng ICollection. Mặc dù bạn chính xác rằng điều này cho phép bạn thêm các mục bằng cách thêm chúng vào bộ sưu tập trên một thực thể liên quan, sans-DAL, chúng vẫn không thể được lưu mà không truy cập vào ngữ cảnh. Nếu bạn đã thiết lập DAL của mình một cách chính xác, điều đó chỉ có sẵn thông qua DAL, do đó bạn vẫn phải chuyển thực thể trở lại đường ống DAL của bạn để duy trì bất kỳ thay đổi nào trong số này. Nói cách khác, đừng lo lắng về nó.

+0

Tôi đang sử dụng IOC. Ngữ cảnh được chia sẻ theo yêu cầu. Trong cùng một yêu cầu nếu tôi đính kèm nó cho một mục đích khác, nó có thể ảnh hưởng. Nhưng bạn là đúng Tôi nghĩ rằng tôi không có bất kỳ hành động mà chọn truy vấn quan hệ sau đó lưu hoặc chỉnh sửa trên cùng một yêu cầu. Nếu tôi có tôi sẽ sử dụng viewmodel mà @CodeCaster nói. –

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