处理RavenDB中

时间:2017-02-05 23:22:30

标签: ravendb

我有一个项目,我有一组表格:

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; }
}

每个&#34;实施&#34;在创建表单时选择的表单模板。

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都可以存在于多个FormTemplates中,表单的值存储为与Form本身相关的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();

尽管我可以说这是正确实现的,但是我已经看到了用.Any实现替换.Contains的建议。取而代之的是,我一直在通过应用连续的.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之间的嵌套关系。

1 个答案:

答案 0 :(得分:0)

你似乎试图以一种主要是关系的方式来做这件事,但你不必这样做。

不要试图拥有一组每个都包含部分数据的独立文档,而只是将它们存储在一个文档中。

{
  "Id": "forms/1234",
  "Name": "Tom",
  "FieldValues": [
   {
      "Id": "FromValues/SchoolDistrictName",
      "Value": "ABi195"
    }
  ],
  "UserId": "users/tom",
  "FormTemplateId": "FromTemplate/1234"
}

这将生成如下所示的文档:

{ "food": {
    "apple": {
        "color": "red"
        },
    "orange": {
        "color": "orange"
        },
    "potato": {
        "color": "brown"
        },
    "tomato": {
        "color": "red"
        }
    }
}

这是一种更自然的建模方式。 此时,您可以使用RavenDB的动态数据索引功能,请参阅此处的文档:

https://ravendb.net/docs/article-page/3.5/Csharp/indexes/using-dynamic-fields