【发布时间】:2017-02-10 06:55:26
【问题描述】:
我有一个项目,其中有一组表格:
public class Form
{
public string Id { get; set; }
public string Name { get; set; }
public IList<string> FieldValueIds { get; set; }
public string UserId { get; set; } // the user who completed the form.
public string FormTemplateId { get; set; }
}
每个“实现”在创建表单时选择的表单模板。
public class FormTemplate
{
public string Id { get; set; }
public string Name { get; set; }
public IList<string> FieldIds { get; set; }
}
它定义了表单中存在哪些字段。每个字段
public class FormField
{
public string Id { get; set; }
public string Name { get; set; }
public string Caption { get; set; }
public ValueType DataType { get; set; } // Enum specifying the type of data this field accepts.
}
存储有关字段的信息,例如描述和期望的类型。每个 FormField 可以存在于多个 FormTemplate 中,表单的值存储为与表单本身相关的 FieldValue 对象。
public class FieldValue
{
public string Id { get; set; }
public string FieldId { get; set; }
public string ValueAsJsonString { get; set; }
}
其他对象包括用户对象:
public class User
{
public string Id { get; set; }
public string Username { get; set; }
public string GivenNames { get; set; }
public string Surname { get; set; }
}
我希望能够执行查询以查找由具有指定名称的用户完成的所有表单,或名称为 X 的字段具有值 Y 的所有表单,等等。
我已经研究了文档 Indexing related documents 中指定的索引的使用情况,但是当我按如下方式实现示例时,文档中介绍的实现引发了 NotSupportedException:
class FormTemplates_ByFieldAndName : AbstractIndexCreationTask<FormTemplate>
{
public class Result
{
public string Name { get; set; }
public IList<string> FieldNames { get; set; }
}
public FormTemplates_ByFieldAndName()
{
Map = FormTemplates => from FormTemplate in FormTemplates
select new
{
Name = FormTemplate.Name,
FieldNames = FormTemplate.FieldIds.Select(x => LoadDocument<FormField>(x).Name)
};
}
}
// in code:
IList<FormTemplate> TestResults = session.Query<FormTemplates_ByFieldAndName.Result, FormTemplates_ByFieldAndName>()
.Where(x => x.Name == "TemplateName" || x.FieldNames.Contains("FieldName"))
.OfType<FormTemplate>()
.ToList();
据我所知,这是正确实现的,但是我看到了一个建议,将 .Contains 替换为 .Any 实现。取而代之的是,我一直在通过应用连续的 .Where 参数来尝试不同的方法。像这样:
var pre = session.Query<FormTemplates_ByFieldAndName.Result, FormTemplates_ByFieldAndName>();
var pr2 = pre.Where(x => x.Name == "TypeTest25");
List<FormTemplate> TestResults = pr2
.Where(x => x.FieldNames.Any(a => a == "field25"))
.OfType<FormTemplate>()
.OrderByScoreDescending()
.ToList();
通过基于提供的预先指定格式的字符串应用连续过滤器,修改系统以更面向工厂的方法执行。
这是我应该采用的实现方式吗?如果不是,我应该改变什么?特别是如果我要继续使用 Indexing 选项,我将如何通过 FormTemplates 将此技术应用于 Forms 和 FormFields 之间的嵌套关系。
【问题讨论】:
标签: ravendb