gpt4 book ai didi

c# - 无法将类型为 'System.Linq.Expressions.MethodCallExpression' 的对象转换为类型 'System.Linq.Expressions.LambdaExpression'

转载 作者:行者123 更新时间:2023-12-05 04:02:39 28 4
gpt4 key购买 nike

我正在使用 EntityFramework 并遇到上述错误。当我调用

var documents = docRepository.GetAllSavedDocuments();
var withRatings = documentFilter.GetDocumentsWithRating(documents, 1);

我得到标题中的错误。

我的代码分为几个类

public class DocRepository
{
public IQueryable<Document> GetAllSavedDocuments(User user)
{
return (from d in AllUsersDocuments(user)
select d)
.Include(d => d.Calculations)
.Include("Calculations.CalculationResults");
}
}

public class DocumentFilter
{
public IQueryable<Tuple<Document, Rating>> GetDocumentsWithRating(IQueryable<Document> documents, int id)
{
return documents.Select(x => new
{
Document = x,
Rating = _ratingsProvider.GetRating.Compile()(x, id)
}).AsEnumerable()
.Select(x => new Tuple<Document, Rating>(x.Document, x.Rating)).AsQueryable().Where(x.Item2 == Rating.Ok);
}
}

public class RatingProvider
{
public Expression<Func<Document, int, Rating>> GetRating
{
get
{
return (document, id) =>
document.Calculations.Where(x => x.CId == id).Any() ?
document.Calculations.Single(x => x.CId == id).Rating.Value :
Rating.Unknown;
}
}
}

额外信息

评级是一个枚举。它在 Calculation 类上可以为空。我最初有 IEnumerable,所以我可以使用 Rating Provider 类中的方法进行过滤,例如:

var c = document.Calculations.SingleOrDefault(x => x.Id == id);
if (c == null)
{
return Rating.None;
}
if (!c.Rating.HasValue)
{
return Rating.None
}
return c.Rating.Value;

但我想让它保持可查询状态,因此我们在 SQL 端执行它,而不是在代码中枚举所有对象。有人可以建议我如何实现这一目标吗?

最佳答案

可以先为_ratingsProvider.GetRating赋值,避免标题错误。

之后您将遇到另一个错误,提示 Entity Framework 不支持您的查询。你需要像 LINQKit https://github.com/scottksmith95/LINQKit 这样的东西. AsExpandable()Invoke(x, id) 来自 LINQKit。

using LinqKit;
    public IQueryable<Tuple<Document, Rating>> GetDocumentsWithRating(IQueryable<Document> documents, int id)
{
var getRatingExpression = _ratingsProvider.GetRating;
return documents.AsExpandable().Select(x => new
{
Document = x,
Rating = getRatingExpression.Invoke(x, id)
}).AsEnumerable()
.Select(x => new Tuple<Document, Rating>(x.Document, x.Rating)).AsQueryable().Where(x.Item2 == Rating.Ok);
}

第二个问题的答案:

    public Expression<Func<Document, int, Rating>> GetRating
{
get
{
return (document, id) =>
document.Calculations.Where(x => x.CId == id).Any() ?
document.Calculations
.Where(x => x.CId == id)
.Select(x => x.Rating.HasValue ? x.Rating.Value : Rating.None)
.Single()
Rating.Unknown;
}
}

第二个问题的 .AsEnumerable() 部分的答案:我猜你的问题来自于使用 Tuple ,尝试定义一个类

public class DocumentRating
{
public Document { get; set; }
public Rating { get; set; }
}
    public IQueryable<DocumentRating> GetDocumentsWithRating(IQueryable<Document> documents, int id)
{
var getRatingExpression = _ratingsProvider.GetRating;
return documents.AsExpandable().Select(x => new DocumentRating
{
Document = x,
Rating = getRatingExpression.Invoke(x, id)
})
.Where(x.Item2 == Rating.Ok);
}

关于c# - 无法将类型为 'System.Linq.Expressions.MethodCallExpression' 的对象转换为类型 'System.Linq.Expressions.LambdaExpression',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54242254/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com