Asp.net mvc 何时公开IEnumerable而不是ICollection?

Asp.net mvc 何时公开IEnumerable而不是ICollection?,asp.net-mvc,entity-framework,ef-code-first,repository-pattern,Asp.net Mvc,Entity Framework,Ef Code First,Repository Pattern,使用IEnumurable 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; } } 对于导航属性,我没有使用IEnumerable进行延迟加

使用
IEnumurable

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; }
}
对于导航属性,我没有使用
IEnumerable
进行延迟加载。因此,我必须通过另一个查询获取该用户的订单

我有
ICollection
导航功能。所以我可以从用户那里获得订单。这看起来很酷。但是,我可以在控制器中向用户添加新订单,而无需使用服务或存储库


它是在控制器级别操纵数据。这是反模式吗?

这里没有真正的选择ICollection来控制一些方面,如绑定查询结果和延迟加载。通过使用
IEnumerable
,您基本上关闭了所有这些功能,但与此同时,EF对底层结构的理解也随之关闭。生成迁移时,EF不会为M2M关系、相关表上的外键等生成任何必需的基础联接表

长和短,使用
ICollection
。虽然这允许您通过简单地将项目添加到相关实体san DAL上的集合来添加项目,但如果不访问上下文,这些项目仍然无法保存。如果您已经正确地设置了DAL,那么这只能通过DAL本身来实现,因此您仍然需要将实体传递回DAL管道以使这些更改永久化。换句话说,别担心

但是[使用
ICollection
]我可以在Controller中添加新订单,而无需使用服务或存储库

您的意思是您可以这样做(假设有一个用于向用户添加订单的viewmodel和一个
SaveChanges()
的地方):

尤其是您可以执行
user.Orders.Add(…)
,这是从服务或存储库层公开实体类型的副作用

如果要避免这种情况,必须定义并公开包含要公开的成员的业务对象:

public class UserController
{
    public ActionResult AddUserOrder(AddUserOrderModel addOrder)
    {
        User user = User.GetByEmail(addOrder.UserEmail);        
        user.Orders.Add(addOrder.Order);
        User.SaveChanges();
    }
}
公共类UserBLL
{
public int Id{get;private set;}
public IEnumerable Orders{get{return_Orders.AsEnumerable();}
私人IEnumerable_订单;
公共用户BLL(用户)
{
Id=user.Id;
_订单=用户订单;
}
公共无效添加命令(命令)
{
_订单。添加(订单);
}
}

我正在使用IOC。每个请求共享的上下文。在同一请求中,如果我出于其他目的提交,则可能会受到影响。但你们是对的,我想我并没有选择关系查询然后根据相同的请求保存或编辑的任何操作。如果我有,我会使用@CodeCaster告诉我的viewmodel。首先,我还认为viewmodel。但我不确定它是否会带来更多的复杂性。如果有必要,我会使用viewmodels。谢谢。重点不是viewmodel,真的。它是BLL或域模型。表示用例的对象(可以拥有订单的用户)。如果您不想暴露内部的数据模型,请使用该选项。为什么返回
\u orders.AsEnumerable()
虽然
\u orders
已经是
IEnumerable
?@Mohamed你是对的,但这是错误的方法。我想返回一个类用户无法修改的集合(可以通过将其强制转换为
ICollection
)。应该是这样,这样用户就可以得到订单的副本。
public class User
{
 public int Id{get;set;}
 public virtual ICollection<Order> Orders { get; set; } 
}

public User GetWithOrders()
{
 var myUser=UserRepository.GetByEmail("email@email.com");
 return myUser;
}
public class UserController
{
    public ActionResult AddUserOrder(AddUserOrderModel addOrder)
    {
        User user = User.GetByEmail(addOrder.UserEmail);        
        user.Orders.Add(addOrder.Order);
        User.SaveChanges();
    }
}
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);
    }
}