【发布时间】:2013-11-14 22:13:08
【问题描述】:
我知道 LINQ 不能使用未映射到数据库列的属性,但我不明白为什么一个 LINQ 语句在非静态方法中工作,但在其中尝试时出现此错误。
这是我的工作方法:
private TemplatesAPIContext db = new TemplatesAPIContext();
// GET api/Template
public IQueryable<TemplateDto> GetTemplates()
{
return db.TemplateModels.Include(t => t.Categories).Select(
x => new TemplateDto
{
TemplateID = x.TemplateID,
Name = x.Name,
HTMLShowcase = x.HTMLShowcase,
ShortDescription = x.ShortDescription,
CreationDate = x.CreationDate,
Downloads = x.Downloads,
Tags = x.Tags,
Categories = db.CategoryModels
.Where(c => x.Categories.Where(a => a.TemplateID == x.TemplateID)
.Select(a => a.CategoryID).Contains(c.CategoryID))
}
);
}
我不想重复这个复杂的 DTO 构建(我实际上仍然需要添加一些其他关系,它会变得更加复杂)并在控制器中的每个方法上键入它,所以我想制作一个 lambda 表达式并将其传递给方法。
所以我这样做了:
private static readonly Expression<Func<TemplateModel, TemplateDto>> AsTemplateDto =
x => new TemplateDto
{
TemplateID = x.TemplateID,
Name = x.Name,
HTMLShowcase = x.HTMLShowcase,
ShortDescription = x.ShortDescription,
CreationDate = x.CreationDate,
Downloads = x.Downloads,
Tags = x.Tags,
Categories = new TemplatesAPIContext().CategoryModels
.Where(c => x.Categories.Where(a => a.TemplateID == x.TemplateID)
.Select(a => a.CategoryID).Contains(c.CategoryID))
};
希望能打电话:
// GET api/Template
public IQueryable<TemplateDto> GetTemplates()
{
return db.TemplateModels.Include(t => t.Categories).Select(AsTemplateDto);
}
但这会返回这个错误,这对我来说没有意义,因为它是完全相同的查询,唯一的区别是我需要在 lambda 中实例化 dbContext,因为我不能使用在控制器中实例化的那个lambda 表达式是静态的。
错误
LINQ to Entities 不支持指定的类型成员“CategoryModels”。仅支持初始化程序、实体成员和实体导航属性。
【问题讨论】:
-
您正试图从一个上下文中查询另一个上下文?无论如何,EF 无法将该方法转换为 SQL 查询(您认为会如何?)
-
让我吃惊的是它在第一个示例中有效。我想我要问的是,如何编写 lambda 表达式以产生与第一个示例相同的查询?
标签: c# linq entity-framework lambda asp.net-web-api