C# 使用LINQ to实体时,将结果从业务层返回到表示层的最佳方法

C# 使用LINQ to实体时,将结果从业务层返回到表示层的最佳方法,c#,entity-framework,C#,Entity Framework,我有一个业务层,该层包含在表示层中使用的DTO。此应用程序使用实体框架 下面是一个名为RoleDTO的类的示例: public class RoleDTO { public Guid RoleId { get; set; } public string RoleName { get; set; } public string RoleDescription { get; set; } public int? OrganizationId { get; set; }

我有一个业务层,该层包含在表示层中使用的DTO。此应用程序使用实体框架

下面是一个名为RoleDTO的类的示例:

public class RoleDTO
{
    public Guid RoleId { get; set; }
    public string RoleName { get; set; }
    public string RoleDescription { get; set; }
    public int? OrganizationId { get; set; } 
}
在BLL中,我希望有一个返回DTO列表的方法。我想知道哪种方法更好:返回IQueryable还是返回DTO列表。虽然我觉得返回IQueryable不是一个好主意,因为连接需要打开。以下是使用不同方法的两种不同方法:

第一种方法

public class RoleBLL
{
    private servicedeskEntities sde;

    public RoleBLL()
    {
        sde = new servicedeskEntities();
    }

    public  IQueryable<RoleDTO> GetAllRoles()
    {
        IQueryable<RoleDTO> role = from r in sde.Roles
                        select new RoleDTO()
                        {
                            RoleId = r.RoleID,
                            RoleName = r.RoleName,
                            RoleDescription = r.RoleDescription,
                            OrganizationId = r.OrganizationId
                        };
        return role;
    }
public static List<RoleDTO> GetAllRoles()
{
    List<RoleDTO> roleDTO = new List<RoleDTO>();
    using (servicedeskEntities sde = new servicedeskEntities())
    {
        var roles = from pri in sde.Roles
                         select new { pri.RoleID, pri.RoleName, pri.RoleDescription };

        //Add the role entites to the DTO list and return. This is necessary as anonymous types can be returned acrosss methods
        foreach (var item in roles)
        {
            RoleDTO roleItem = new RoleDTO();
            roleItem.RoleId = item.RoleID;
            roleItem.RoleDescription = item.RoleDescription;
            roleItem.RoleName = item.RoleName;
            roleDTO.Add(roleItem);

        }
        return roleDTO;
    }
}
公共类RoleBLL
{
私人服务实体sde;
公共角色扮演
{
sde=新servicedeskEntities();
}
公共IQueryable GetAllRoles()
{
IQueryable role=来自sde.Roles中的r
选择新角色到()
{
RoleId=r.RoleId,
RoleName=r.RoleName,
RoleDescription=r.RoleDescription,
OrganizationId=r.OrganizationId
};
返回角色;
}
注意:在上述方法中,DataContext是一个私有属性,并在构造函数中设置,因此连接保持打开状态

第二种方法

public class RoleBLL
{
    private servicedeskEntities sde;

    public RoleBLL()
    {
        sde = new servicedeskEntities();
    }

    public  IQueryable<RoleDTO> GetAllRoles()
    {
        IQueryable<RoleDTO> role = from r in sde.Roles
                        select new RoleDTO()
                        {
                            RoleId = r.RoleID,
                            RoleName = r.RoleName,
                            RoleDescription = r.RoleDescription,
                            OrganizationId = r.OrganizationId
                        };
        return role;
    }
public static List<RoleDTO> GetAllRoles()
{
    List<RoleDTO> roleDTO = new List<RoleDTO>();
    using (servicedeskEntities sde = new servicedeskEntities())
    {
        var roles = from pri in sde.Roles
                         select new { pri.RoleID, pri.RoleName, pri.RoleDescription };

        //Add the role entites to the DTO list and return. This is necessary as anonymous types can be returned acrosss methods
        foreach (var item in roles)
        {
            RoleDTO roleItem = new RoleDTO();
            roleItem.RoleId = item.RoleID;
            roleItem.RoleDescription = item.RoleDescription;
            roleItem.RoleName = item.RoleName;
            roleDTO.Add(roleItem);

        }
        return roleDTO;
    }
}
公共静态列表GetAllRoles()
{
List roleDTO=新列表();
使用(servicedeskEntities sde=new servicedeskEntities())
{
变量角色=来自sde.roles中的pri
选择新{pri.RoleID,pri.RoleName,pri.RoleDescription};
//将角色实体添加到DTO列表并返回。这是必要的,因为匿名类型可以通过SSS方法返回
foreach(角色中的变量项)
{
RoleDTO roleItem=新RoleDTO();
roleItem.RoleId=item.RoleId;
roleItem.RoleDescription=item.RoleDescription;
roleItem.RoleName=item.RoleName;
添加(roleItem);
}
返回角色到;
}
}

如果有更好的方法,请告诉我。

最好不要将模型对象直接发送到表示层,您可以使用一个中间层,将这些DTO对象映射到表示层需要的自定义对象


这与您的第二种方法很接近,但并不完全相同。

您能否更清楚地了解第一种方法的问题所在。它是关注点分离吗?我确实更喜欢第二种方法,但您能否解释一下实现这一点的确切方法?我提到的方法有三个优点,第一个是co分离ncerns,第二个是几乎所有的时候,您的表示层可能不会消耗整个DTO,因此通过为表示层定制对象,您可以发送足够的信息,第三个是您可以对您发送到表示层而不是直接发送到DTO对象的自定义对象执行验证等。举个例子,我通常使用ASP.NET MVC,我总是创建ViewModel对象,将需要从DTO发送到表示层的数据复制到其中,并将ViewModel对象发送到表示层。我对ViewModel对象SOK进行验证。我认为这里有点混乱。DTO包含定制的属性至少,在我的演员阵容中,我是这样设置的。RoleBLL类应该完全按照你说的做。它将有一个名为“GetAllRoles()的方法”这也是处理验证/异常的地方。如果您查看我的另一个方法,它将返回DTO的iQueryable。这将再次成形以匹配表示层中的要求。(只发送必需的字段)。