Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
lambda表达式中的C#LINQ to SQL指定类型成员_C#_Linq_Entity Framework_Lambda_Asp.net Web Api - Fatal编程技术网

lambda表达式中的C#LINQ to SQL指定类型成员

lambda表达式中的C#LINQ to SQL指定类型成员,c#,linq,entity-framework,lambda,asp.net-web-api,C#,Linq,Entity Framework,Lambda,Asp.net Web Api,我知道LINQ不能使用未映射到数据库列的属性,尽管我不明白为什么一个LINQ语句在非静态方法中工作,但我在尝试在一个方法中工作时遇到了这个错误 以下是我的工作方法: private TemplatesAPIContext db = new TemplatesAPIContext(); // GET api/Template public IQueryable<TemplateDto> GetTemplates() { return db.TemplateModels.Inc

我知道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))
        }
    );
}
private TemplatesAPIContext db=new TemplatesAPIContext();
//获取api/模板
公共IQueryable GetTemplates()
{
返回db.TemplateModels.Include(t=>t.Categories)。选择(
x=>新模板到
{
TemplateID=x.TemplateID,
Name=x.Name,
HTMLShowcase=x.HTMLShowcase,
ShortDescription=x.ShortDescription,
CreationDate=x.CreationDate,
下载=x.下载,
标签=x。标签,
类别=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))
    };
私有静态只读表达式AsTemplateDto=
x=>新模板到
{
TemplateID=x.TemplateID,
Name=x.Name,
HTMLShowcase=x.HTMLShowcase,
ShortDescription=x.ShortDescription,
CreationDate=x.CreationDate,
下载=x.下载,
标签=x。标签,
Categories=新模板sapiContext().categorimodels
.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);
}
//获取api/模板
公共IQueryable GetTemplates()
{
返回db.TemplateModels.Include(t=>t.Categories)。选择(AsTemplateDto);
}
但这返回了这个错误,这对我来说没有意义,因为它是完全相同的查询,唯一的区别是我需要在lambda中实例化dbContext,因为我不能使用在控制器中实例化的dbContext,因为lambda表达式是静态的

错误 LINQ to实体中不支持指定的类型成员“CategoryModels”。仅支持初始值设定项、实体成员和实体导航属性


在查询中使用与进行查询的上下文相同的上下文是很重要的,这样查询提供者才能理解您试图做什么。所以你所需要的是一种复制特定于给定上下文的表达式的方法,这并不难,你已经完成了几乎所有的工作

//TODO rename method as appropriate
private static Expression<Func<TemplateModel, TemplateDto>> 
    CreateTemplateDTO(TemplatesAPIContext context)
{
    return 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 = context.CategoryModels
            .Where(c => x.Categories.Where(a => a.TemplateID == x.TemplateID)
            .Select(a => a.CategoryID).Contains(c.CategoryID))
    };
}
//TODO根据需要重命名方法
私有静态表达式
CreateTemplateDTO(TemplatesAPIContext上下文)
{
返回x=>newtemplatedto
{
TemplateID=x.TemplateID,
Name=x.Name,
HTMLShowcase=x.HTMLShowcase,
ShortDescription=x.ShortDescription,
CreationDate=x.CreationDate,
下载=x.下载,
标签=x。标签,
类别=context.CategoryModels
.Where(c=>x.Categories.Where(a=>a.TemplateID==x.TemplateID)
.Select(a=>a.CategoryID).Contains(c.CategoryID))
};
}
现在你可以写:

public IQueryable<TemplateDto> GetTemplates()
{
    return db.TemplateModels.Include(t => t.Categories)
        .Select(CreateTemplateDTO(db));
}
public IQueryable GetTemplates()
{
返回db.TemplateModels.Include(t=>t.Categories)
.选择(CreateTemplateDTO(db));
}

您的第一个方法是一个简单的表达式树,它只包含树节点中的简单操作(如将a分配给B),因此可以轻松地将其编译为SQL查询。

另一个方法包含TemplatesAPIContext的实例化。无法进行数据库查询。

您正在尝试从一个上下文查询另一个上下文?无论如何,EF无法将该方法转换为SQL查询(您认为会是怎样的?)让我感到困惑的是,它在第一个示例中工作。我想我要问的是,如何编写lambda表达式以产生与第一个示例相同的查询?嗯,我想我尝试将上下文作为参数传递给表达式,但它给了我一些错误,让我再试一次。@francisco.preller您几乎肯定无法将其作为字段来执行;它需要是一个方法,或者充其量是一个属性,但是一个方法最好。啊,得到了它,必须把它变成一个方法,而不仅仅是一个属性。谢谢,这很有效。老兄,我是如此接近>@francisco.preller是的,当你完成了95%的工作时,我几乎为获得解决方案的荣誉而感到难过。我很抱歉不得不问,但从昨晚起我就一直在为此而头痛:P