1

我想要一种可以查询整个 RavenDB 数据库的方法。

我的方法签名如下所示:

public static DataTable GetData(string className, int amount, string orderByProperty, string filterByProperty, string filterByOperator, string filterCompare)

我想我可以使用动态 LuceneQuery 完成以上所有工作。

session.Advanced.LuceneQuery<dynamic>();

问题是:由于我dynamic在给定的类型中使用,我如何确保查询只包含与className匹配的类型?

我正在寻找类似的东西.WhereType(className)or .Where("type: " + className)

解决方案

这将返回正确类型的结果:

var type = Type.GetType("Business.Data.DTO." + className);

var tagName = RavenDb.GetTypeTagName(type);
using (var session = RavenDb.OpenSession())
{
    var result = session.Advanced
                        .LuceneQuery<object, RavenDocumentsByEntityName>()
                        .WhereEquals("Tag", tagName)
                        .ToList();
}

请注意,无法为此添加额外的“WhereEquals”或其他过滤器。这是因为“RavenDocumentByEntityName”索引中不包含特定于该文档类型的任何内容。

这意味着该解决方案不能用于我想要完成的任务。

我最终做了什么

虽然它不能完全满足我的要求,但这就是我最终要做的:

public static List<T> GetData<T>(DataQuery query)
{
    using (var session = RavenDb.OpenSession())
    {
        var result = session.Advanced.LuceneQuery<T>();

        if (!string.IsNullOrEmpty(query.FilterByProperty))
        {
            if (query.FilterByOperator == "=")
            {
                result = result.WhereEquals(query.FilterByProperty, query.FilterCompare);
            }
            else if (query.FilterByOperator == "StartsWith")
            {
                result = result.WhereStartsWith(query.FilterByProperty, query.FilterCompare);
            }
            else if (query.FilterByOperator == "EndsWith")
            {
                result = result.WhereEndsWith(query.FilterByProperty, query.FilterCompare);
            }
        }

        if (!string.IsNullOrEmpty(query.OrderByProperty))
        {
            if (query.Descending)
            {
                result = result.OrderBy(query.OrderByProperty);
            }
            else
            {
                result = result.OrderByDescending(query.OrderByProperty);
            }
        }

        result = result.Skip(query.Skip).Take(query.Amount);

        return result.ToList();
    }
}

尽管这肯定是一种反模式,但它是一种查看某些数据的巧妙方法,如果这是您想要的。它很容易像这样调用:

DataQuery query = new DataQuery
{
    Amount = int.Parse(txtAmount.Text),
    Skip = 0,
    FilterByProperty = ddlFilterBy.SelectedValue,
    FilterByOperator = ddlOperator.SelectedValue,
    FilterCompare = txtCompare.Text,
    OrderByProperty = ddlOrderBy.SelectedValue,
    Descending = chkDescending.Checked
};

grdData.DataSource = DataService.GetData<Server>(query);
grdData.DataBind();

“服务器”是我正在使用的类/文档类型之一,因此它不是完全动态的缺点是我必须为每种类型定义一个这样的调用。

4

1 回答 1

1

我强烈建议你不要走这条路。您实际上是在尝试隐藏 RavenDB Session 对象,该对象非常强大并且可以直接使用。

仅查看您要创建的方法的签名,参数都非常严格,并且对您正在处理的数据做出了许多可能不正确的假设。和返回类型 - 你为什么要返回 a DataTable?也许返回 aobject或 a dynamic,但 Raven 中的任何内容都不是在表格中结构化的,所以这DataTable是一个坏主意。

要回答特定问题,类型名称来自Raven-Entity-Name元数据,您需要在其上构建索引。当您使用索引中的from docs.YourEntity语法进行索引时,这会自动发生。.Query<YourEntity>当您使用动态索引(例如or )时,Raven 在幕后执行此操作.Advanced.LuceneQuery<YourEntity>

不过,你不应该这样做。

于 2013-04-01T18:59:09.160 回答