c# - RavenDB 嵌套 LINQ 表达式的解决方法

标签 c# linq ravendb

我在 RavenDB 中存储了一组简单的对象:

public class Question
{
    public string Id { get; set; }
    public DateTime CreatedOn { get; set; }
    public ICollection<User> Supporters { get; set; }
    public ICollection<Answer> Answers { get; set; }
}

public class Answer 
{
    public string Id { get; set; }
    public bool IsOfficial { get; set; }
}

现在我想查询 RavenDB 给我一组问题,首先按支持者数量排序,然后按条件排序 - 如果问题有任何官方答案,然后按问题创建日期排序。所以我写了一个查询:

var questions = DocumentSession.Query<Question>().AsQueryable(); 
questions = questions
                .OrderByDescending(x => x.Supporters.Count)
                .ThenByDescending(x => x.Answers.Any(a => a.IsOfficial)) //EDIT: source of exception
                .ThenByDescending(x => x.CreatedOn)
                .Take(15);                
var result = questions.ToList();

抛出异常:

System.InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.MethodCallExpressionN' to type 'System.Linq.Expressions.MemberExpression'

当我使用 linq-to-objects 时,查询在逻辑上是正确的并且有效,只需将 .ToList() 添加到第一行:

var questions = DocumentSession.Query<Question>().Tolist().AsQueryable();
// next lines stay unchanged

由于性能问题,我不想这样做(此更改强制在过滤之前将所有问题从数据库加载到内存中)。

如何在不影响性能的情况下使其工作?也许 shell 我定义了一个索引?那么它应该是什么样子?

最佳答案

用于您目的的自定义索引基本上将是您的类的重新创建,其中包含额外的字段(以及一些支持它的逻辑)。您似乎不想向当前类添加更多字段,您可以向项目添加更多类吗?

这是一个例子:

public class Question_WithAnyOfficial: AbstractIndexCreationTask<Question>
{
    public class Question_WithAnyOfficial()
    {
        Map = questions => from question in questions
                           // New Anonymous Type
                           select new
                           {
                                Id = question.Id,
                                CreatedOn = question.CreatedOn,
                                Supporters = question.Supporters,
                                Answers = question.Answers,
                                AnyOfficial = question.Answers.Where(a => a.IsOfficial).Any()
                           };
    }
}

然后你可以这样查询:

var questions = DocumentSession.Query<Question_WithAnyOfficial>()
                .OrderByDescending(x => x.Supporters.Count)
                .ThenByDescending(x => x.AnyOfficial)
                .ThenByDescending(x => x.CreatedOn)
                .Take(15)
                .ToList();         

不要忘记,您必须在应用启动时注册索引。

关于c# - RavenDB 嵌套 LINQ 表达式的解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10189966/

相关文章:

c# - 了解 Azure Functions HttpTrigger 缩放算法

c# - 异步保存 Outlook.MailItem?

c# - NHibernate LINQ 查询中的关键回退

c# - "where"使用 linq xml 查询

c# - 告诉 RavenDB 忽略一个属性

c# - 从 URL 获取整个字符串,包括非查询字符串 C#

c# - 跟踪方法执行时间

c# - 我怎样才能从一个非类型化的表达式返回到一个类型化的表达式?

ravendb - 如何通过 C# 获取 RavenDB 文档的上次写入日期

python-3.x - 是否可以使用 python/pyspark 从 RavenDB 中的数据库加载整个集合?