C# 关于项目的ASP.NET MVC、EF层和自动映射设置的建议

C# 关于项目的ASP.NET MVC、EF层和自动映射设置的建议,c#,asp.net,asp.net-mvc,entity-framework,dto,C#,Asp.net,Asp.net Mvc,Entity Framework,Dto,我正试图找出设计这个项目的最佳方法。基本上,这是一个“乐队”简介网站。我正在使用ASP.NET4、EF和Automapper(也使用structuremap,但这并不重要)。我遇到了性能问题,需要关于我的方法是否正确的建议(我猜不是)。我将重点介绍特定的部分,并提供精简的示例 我有一个EntityFramework存储库类,它使用LINQ直接与EF对象交互: [Pluggable("Repository")] public class EntityDataRepository : IReposi

我正试图找出设计这个项目的最佳方法。基本上,这是一个“乐队”简介网站。我正在使用ASP.NET4、EF和Automapper(也使用structuremap,但这并不重要)。我遇到了性能问题,需要关于我的方法是否正确的建议(我猜不是)。我将重点介绍特定的部分,并提供精简的示例

我有一个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);
        }
    }
}
[可插入(“存储库”)]
公共类EntityDataRepository:IRepository
{
静态EntityDataRepository()
{
//删除了其他映射
//对象是EF对象,映射到我的DTO类
CreateMap();
CreateMap();
CreateMap();
}
公共IEnumerable GetBandsByUser(Guid用户ID)
{
使用(var ctx=new DbContext())
{
var user=GetCurrentUserModel(ctx,userId);
var efBands=来自user.band关系中的r
订购人r.日期
选择r波段;
返回Mapper.Map(efBands);
}
}
}
乐队有风格和活动。注意,它将EF对象映射到我的DTO对象,并返回它们的列表。它充当代理,使我的控制器能够调用上的方法以获取它所需的数据(实际逻辑经过更改以显示我所需的数据):

名称空间OpenGrooves.Web.Areas.Edit.Controllers
{
[授权]
公共类MyBandsController:BaseController
{
公共行动结果展示带()
{
IEnumerable bands=repository.GetBandsByUser(loggedUserGuid).First();
返回视图(带);
}
}
}
最后,这里是BandModel类,它镜像EF中的Band类实体:

public class BandModel
{
    // fluff and scalar properties removed
    public IEnumerable<EventModel> Events { get; set; }
    public IEnumerable<GenreModel> Genres { get; set; }
}
公共类模型
{
//已删除绒毛和标量属性
公共IEnumerable事件{get;set;}
公共IEnumerable类型{get;set;}
}
基本上,我做得对吗?在my EF to DTO类中,Band EF实体具有导航属性,例如类型和事件。问题是,在automapper中进行映射的过程中,这些列表属性正在被填充,特别是当我的一个代理方法返回BandModels列表时。它似乎在为每个记录调用类型和事件EF查询,这显然是一个主要的性能杀手(对于返回的每个BandModel对象,至少运行2个事件和类型查询)

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

在我的控制器中直接使用EF对象,甚至可能用作视图的模型,这样可以吗

是的,有点

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

有些人不喜欢太棒,包括其他语言和框架,比如每个PHPMVC框架、Rails和Django。没有人可以说这些语言“做错了”,但美国.NET开发人员采用了不同的模式


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


默认情况下,EF4中的延迟加载是打开的。

在第二个问题中,他指的是,从EF对象创建DT对象的自动映射器正在命中那些延迟加载的属性并导致它们加载。@patmortech-我明白了,但是“我的映射中是否有什么需要更改以启用延迟加载?”-无法启用已启用的内容。;)在我的代码中,EF中有一个Band对象和一个BandModel(用于视图模型)。这两个对象都具有IEnumerable事件和流派属性。当从EF映射到DTO时,这些属性将被延迟加载(如果我只是直接使用EF对象),它们将被加载到每个BandModel对象。也就是说,如果我输出一个BandModels列表(如上所述),它将加载每个对象的事件和类型。因此,它不仅调用一个查询来获取波段列表,而且每次波段迭代调用2个查询(如果是10个波段,则为21个查询)。@Ryan Peters-对,这是设计的,您需要急切地加载这些导航属性。
public class BandModel
{
    // fluff and scalar properties removed
    public IEnumerable<EventModel> Events { get; set; }
    public IEnumerable<GenreModel> Genres { get; set; }
}