【问题标题】:Advice on my ASP.NET MVC, EF layer, and Automapper setup for a project关于我为项目设置 ASP.NET MVC、EF 层和 Automapper 的建议
【发布时间】:2011-01-17 02:19:02
【问题描述】:

我正在尝试找出构建这个项目的最佳方法。基本上,它是一个“乐队”个人资料网站。我正在使用 ASP.NET 4、EF 和 Automapper(结构图也是如此,但这并不重要)。我遇到了性能问题,需要关于我的方法是否正确的建议(我的猜测不是)。我将专注于特定部分并提供精简示例。

我有一个 EntityFramework 存储库类,它使用 LINQ 直接与 EF 对象交互:

[Pluggable("Repository")]
public class EntityDataRepository : IRepository
{
    static EntityDataRepository()
    {
        // other mappings removed
        // Data. objects are EF objects, mapping to my DTO classes
        Mapper.CreateMap<Data.Event, Models.EventModel>();
        Mapper.CreateMap<Data.Genre, Models.GenreModel>();
        Mapper.CreateMap<Data.Band, Models.BandModel>();
    }

    public IEnumerable<BandModel> GetBandsByUser(Guid userId)
    {
        using (var ctx = new DbContext())
        {
            var user = GetCurrentUserModel(ctx, userId);

            var efBands = from r in user.BandRelations
                            orderby r.Date
                            select r.Band;

            return Mapper.Map<IEnumerable<Data.Band>, IEnumerable<Models.BandModel>>(efBands);
        }
    }
}

乐队有流派和事件。请注意,它将 EF 对象映射到我的 DTO 对象,并返回它们的列表。它充当代理,使我的控制器能够调用方法以获取所需的数据(实际逻辑已更改以显示我需要的内容):

namespace OpenGrooves.Web.Areas.Edit.Controllers
{
    [Authorize]
    public class MyBandsController : BaseController
    {
        public ActionResult ShowBands()
        {
            IEnumerable<BandModel> bands = repository.GetBandsByUser(loggedUserGuid).First();

            return View(bands);
        }
    }
}

最后,这是 BandModel 类,它反映了 EF 中的 Band 类实体:

public class BandModel
{
    // fluff and scalar properties removed
    public IEnumerable<EventModel> Events { get; set; }
    public IEnumerable<GenreModel> Genres { get; set; }
}

基本上,我这样做对吗?在我的 EF 到 DTO 类中,Band EF 实体具有导航属性,例如流派和事件。问题是,在 automapper 中进行映射期间,正在填充这些列表属性,特别是如果我的代理方法之一返回 BandModels 列表。它似乎在为每条记录调用 Genres 和 Event EF 查询,这显然是一个主要的性能杀手(对于每个返回的 BandModel 对象,至少运行 2 个 Events 和 Genres 查询)。

  • 直接在我的控制器中使用 EF 对象是否可行,甚至可能用作视图的模型?
  • 我是否需要在映射中更改某些内容以启用这些导航属性(事件、BandModel 对象的流派)的延迟加载?

谢谢!!

【问题讨论】:

    标签: c# asp.net asp.net-mvc entity-framework dto


    【解决方案1】:

    直接在我的控制器中使用 EF 对象是否可行,甚至可能用作视图的模型?

    是的,有点。

    这个答案是主观的,取决于您如何看待关注点分离。大多数 MVC 开发人员,包括我在内,都对视图模型发誓。它将您的数据或域类与表示层分离。这太棒了。

    有些人不喜欢出色,包括其他语言和框架,例如每个 PHP MVC 框架、Rails 和 Django。没有人可以说这些语言“做错了”,但我们 .NET 开发人员遵循不同的范式。


    您的第二个问题很奇怪,在您说正在发生延迟加载之后,您说“有什么东西可以启用延迟加载”。需要解释一下吗?

    在 EF4 中默认开启延迟加载。

    【讨论】:

    • 在第二个问题中,他指的是从 EF 对象创建其 DT 对象的自动映射器正在命中那些延迟加载的属性并导致它们加载。
    • @patmortech - 我明白了,但随后出现“我的映射是否需要更改以启用延迟加载” - 无法启用已启用的功能。 ;)
    • 在我的代码中,我在 EF 中有一个 Band 对象和一个 BandModel(用于视图模型)。这两个对象都有 IEnumerable Events 和 Genre 属性。当从 EF 映射到 DTO 时,虽然这些属性会被延迟加载(如果我只是直接使用 EF 对象),它们会为每个 BandModel 对象加载。意思是,如果我输出一个 BandModel 列表(如上),它会为每个对象加载事件和流派。因此,它不仅调用一个查询来获取频段列表,而且每次频段迭代调用 2 个查询(如果是 10 个频段,则为 21 个查询)。
    • @Ryan Peters - 没错,这就是设计,您需要急切地加载这些导航属性。 msdn.microsoft.com/en-us/library/bb896272.aspx
    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多