首页 > 解决方案 > 如何编写动态选择表达式

问题描述

我需要在实体框架上编写一些动态选择表达式,例如示例中的内容。

var list = db.Article
    .GroupBy(x => x.CategoryId)
    .Select(x => new ArtDto
    {
        No = x.Select(c => c.NUMBER).FirstOrDefault(),
        UserName = x.Key,
        Count = x.Count()
    })
    .ToList();

我可以用这样的表达式编写 group by:

Expression<Func<Article, int>> groupByExp;
groupByExp = (x) => x.CategoryId;

所以我可以用 groupByExp 替换实际的表达式。

var list = db.Article
    .GroupBy(groupByExp)
    .Select(x => new ArtDto
    {
        No = x.Select(c => c.NUMBER).FirstOrDefault(),
        UserName = x.Key,
        Count = x.Count()
    })
    .ToList();

我还想为选择写另一个表达式。所以我可以将它发送到另一个函数,它将在该函数上是动态的。

Expression<Func<Article, bool>> selectExp;
selectExp = (x) => new ArtDto { ... };

可能吗?您对此有任何想法或教程吗?

标签: c#asp.net-mvcentity-framework

解决方案


对的,这是可能的,

在开始之前,您需要:

  • 为选定的属性创建新对象
  • 将您的模型映射到新对象

让我们考虑一下你有你的模型Article,你需要返回新模型ArticleSummary,如下所示

public class Article {
 public int id { get; set; }
 public string Title { get; set; }
 public string Introduction { get; set; }
 public string AuthorId { get; set; }
 public AppUser Author { get; set; }
 public DateTime PublishDate { get; set; }
}

public class ArticleSummary {
 public int Id { get; set; }
 public string Title { get; set; }
 public string Introduction { get; set; }
}

这是映射:

Expression<Func<Article, ArticleSummary>> mapArticle = x => new ArticleSummary {
    Id = x.Id,
    Title = x.Title,
    Introduction = x.Introduction
};

这是“简化的”数据函数:

// T is Article model
// U is ArticleSummary model
public async Task<ICollection<U>> SelectListAsync<T, U>(
            Expression<Func<T, bool>> search,
            Expression<Func<T, U>> select) where T : class
{
    var query =
    _context.Set<T>()
    .Where(search)
    .Select(select);

    return await query.ToListAsync();
}

您可以通过将映射表达式传递给选择属性来调用它。


推荐阅读