我需要在实体框架上编写一些动态选择表达式,如示例中所示。
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();
我可以用这样的表达式编写分组依据:
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 { ... };
有可能吗?您有任何想法或教程吗?
答案 0 :(得分:2)
是的,
开始之前,您需要:
让我们认为您拥有模型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();
}
您可以通过传递映射表达式来选择属性来调用它。
答案 1 :(得分:1)
您的表达式应将IIGrouping<T, Article>
作为第一个参数(其中T
是CategoryId
的类型)。假设CategoryId是int
表达式,可以这样写:
public static Expression<Func<IGrouping<int, Article>, ArtDto>> SelectExpression()
{
return x => new ArtDto
{
No = x.Select(c => c.NUMBER).FirstOrDefault(),
UserName = x.Key,
Count = x.Count()
};
}