【问题标题】:ASP.NET MVC N-Tier application with WCF and entity framework efficient loading具有 WCF 和实体框架高效加载的 ASP.NET MVC N-Tier 应用程序
【发布时间】:2013-06-24 08:38:02
【问题描述】:

我正在寻求一些关于以有效方式使用实体框架和从 MVC 应用程序调用的 WCF 服务的建议。

我有一个 ASP.NET MVC Web 应用程序作为表示层,它调用 WCF 服务来执行所有数据操作。 WCF 应用程序使用实体框架对 DB 执行操作。

问题在于,根据正在呈现的页面,数据库所需的信息会发生变化,例如,如果我想显示所有用户的列表,我可能只想要他们的用户名,但 WCF 服务会返回整个模型,当处理大量记录时,这显然变得非常低效。

有什么方法可以提高效率,需要以某种方式在 Linq 语句中指定 Include 和 Select 的值

【问题讨论】:

    标签: asp.net-mvc wcf entity-framework


    【解决方案1】:

    如果我没听错,您实际上是在说您的 Models 与您的 Views 的需求不兼容。

    这就是为什么人们使用Data Transfer Objects (DTO) 作为从数据服务返回的对象而不是实体本身的原因之一。

    通常,您需要将您的实体project / map 放入 DTO 对象中。

    例如,如果我想显示所有用户的列表,我可能只是 想要他们的用户名,但 WCF 服务会返回整个模型

    对于这种特殊情况,您可以尝试以下方法:

    // Your 'User' Entity
    public class User : BaseEntity
    {
        public int Id { get; set; }
        public string Username { get; set; }
        public string Email { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public virtual ICollection<Phone> Phones { get; set; }
    }
    
    // Base class for all 'Mappable' DTOs
    public abstract class Mappable<ENTITY, DTO> where ENTITY : BaseEntity
    {
        public abstract DTO ToDTO(ENTITY entity);
    }
    
    // Your DTO (specific to your grid needs)
    public class UsersGridDTO : Mappable<User, UsersGridDTO>
    {
        public int Id { get; set; }
        public string Username { get; set; }
    
        public override UsersGridDTO ToDTO(User entity)
        {
            return new UsersGridDTO
            {
                Id = entity.Id,
                Username = entity.Username
            };
        }
    }
    
    // In your WCF data service
    public IEnumerable<DTO> GetData<DTO>() where DTO : Mappable<Entity, DTO>, new()
    {
        return efContext.Users.Select(new DTO().ToDTO);
    }
    

    此外,当使用 Asp.Net MVC 时,DTO 可以用作您的ViewModels(参见here)。

    您还可以使用像 AutoMapper 这样的框架来为您处理实体到 DTO 的映射。

    【讨论】:

    • 听起来正是我所追求的。唯一的另一件事是,有没有办法在实体框架的急切加载中使用这种方法。对于您的示例,如果我想要另一个具有电话集合的 DTO。显然映射可以只引用模型中的 Phones 属性,但如果它没有加载,这将是对数据库的另一个调用?
    • 由于(默认情况下)实体框架使用Dynamic Proxy 包装您的实体,该Dynamic Proxy 按需启动“get-from-db”调用,User 实体被传递给@987654331 @ 方法也是一个代理,将能够使用延迟加载填充您的 Phones 集合。
    • 据我了解,延迟加载将使用另一个数据库调用,这会是大型记录集的性能问题吗?
    • 处理大型数据集时,这可能是个问题。这就是为什么您可以使用Include 方法Eager Load 一些数据。但这值得再次讨论。
    • 感谢您的详细解答,非常有帮助
    猜你喜欢
    • 2014-12-10
    • 2012-03-28
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多