【问题标题】:Implicit ViewModel generation from LINQ?来自 LINQ 的隐式 ViewModel 生成?
【发布时间】:2016-12-03 12:56:56
【问题描述】:

在我的项目中,我有一个被许多实体使用的 GenericImageViewModel

获取 ASP 用户实体的示例:

var query = UserRepository.Get(Id).Select(a => new TRDIdenityViewModel
            {
                FirstName = a.UserProfile.FirstName,
                LastName = a.UserProfile.LastName,
                NickName = a.UserProfile.NickName,
                ProfileImage = a.UserProfile.ProfileImage
            });

ProfileImage 是 GenericImageViewModel 并具有如下隐式运算符:

 public static implicit operator TRDGenericImageViewModel(TRDImage image)
    {
        return new TRDGenericImageViewModel
        {
            Id = image.Id,
            AspectRatio = image.Ratio,
            Url = image.Url,
        };
    }

如果我运行查询 Entity Framework 会抛出异常:

“无法将类型 'TRDImage' 转换为类型 'TRDGenericImageViewModel'。LINQ to Entities 仅支持转换 EDM 基元或枚举类型。”

如果我为每个 ViewModel 手动创建 GenericImageViewModel,一切运行良好:

var query = UserRepository.Get(Id).Select(a => new TRDIdenityViewModel
            {
                FirstName = a.UserProfile.FirstName,
                LastName = a.UserProfile.LastName,
                NickName = a.UserProfile.NickName,
                ProfileImage = new TRDGenericImageViewModel {
                    Id = a.UserProfile.ProfileImage.Id,
                    AspectRatio = a.UserProfile.ProfileImage.Ratio,
                    Url = a.UserProfile.ProfileImage.Url,
                },
            });

但在这种情况下,我必须在每个 ViewModel 中复制并粘贴 TRDGenericImageViewModel 生成,这不是应该的方式。如果有什么改变,我必须修改所有相关的类。

那么有没有办法避免这个异常呢?

【问题讨论】:

  • 您可以通过在创建自定义 ViewModel 类实例的 lambda 之前使用 .AsEnumerable() 来解决此问题。
  • 在 lambda 从数据库中获取实体之前使用 .AsEnumerable()。所以不可能Count() 不包括在基本查询中的相关实体。
  • 您的发帖并未表明对Count的任何调用
  • 我的错。更新答案。

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


【解决方案1】:

由于稍后在该查询中进行选择,因此无法使用 .AsEnumerable() 先前的 lambda。

var query = UserRepository
            .Get(Id)
            .AsEnumerable()
            .Select(a => new TRDIdenityViewModel
            {
                FirstName = a.UserProfile.FirstName,
                LastName = a.UserProfile.LastName,
                NickName = a.UserProfile.NickName,
                ProfileImage = new TRDGenericImageViewModel
                {
                    Id = a.UserProfile.ProfileImage.Id,
                    AspectRatio = a.UserProfile.ProfileImage.Ratio,
                    Url = a.UserProfile.ProfileImage.Url,
                },
                Statistics = new TRDUserStatisticsViewModel
                {
                    PostCount = a.Posts.Count(),
                    CommentCount = a.Comments.Count(),
                    ImageCount = a.Images.Count(),
                    VideoCount = a.Videos.Count(),
                    VoteCount = a.PostVotes.Count(),
                }
            });

当调用.AsEnumerable() 时,只计算 Include 语句中包含的实体。但如果用户有超过 1000 个帖子和 10.000 个投票,那么查询就是一场数据噩梦。

【讨论】:

  • 我建议放弃存储库模式并直接使用您的 EF 实体对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 2017-01-08
  • 2019-09-27
  • 2012-09-16
  • 1970-01-01
  • 2013-04-25
  • 1970-01-01
相关资源
最近更新 更多