在RavenDB Map / Reduces中处理可空字段的正确方法?

时间:2012-08-21 18:56:39

标签: map mapreduce ravendb nullable reduce

如何映射具有可空字段的对象?我想我必须把可空字段变成一个不可空的版本,这就是我偶然发现的那一步。

映射可空属性的正确方法是什么?

public class Visit {
    public string Id { get; set; }
    public int? MediaSourceId { get; set; }
}

public class MapReduceResult
{
    public string VisitId { get; set; }
    public int MediaSourceId { get; set; }
    public string Version { get; set; }
    public int Count { get; set; }
}

AddMap<Visit>(
    visits =>
    from visit in visits
    select new
        {
            VisitId = visit.Id,
            MediaSourceId =
                (visit.MediaSourceId.HasValue)
                ? visit.MediaSourceId
                : UNUSED_MEDIASOURCE_ID,
            Version = (string) null,
            Count = 1
        });

这不起作用!事实上;这个地图完全被忽略了,而其他地图工作正常,它们最终会按预期减少。

感谢您的帮助!

下面是一个新添加的测试用例,它失败并显示“无法将&lt; null&gt;赋值给匿名类型属性”。我怎么能以最少的痛苦得到这个飞行?

[TestFixture]
public class MyIndexTest
{
    private IDocumentStore _documentStore;

    [SetUp]
    public void SetUp()
    {
        _documentStore = new EmbeddableDocumentStore {RunInMemory = true}.Initialize();
        _documentStore.DatabaseCommands.DisableAllCaching();

        IndexCreation.CreateIndexes(typeof (MyIndex).Assembly, _documentStore);
    }

    [TearDown]
    public void TearDown()
    {
        _documentStore.Dispose();
    }

    [Test]
    public void ShouldWork()
    {
        InitData();

        IList<MyIndex.MapReduceResult> mapReduceResults = null;
        using (var session = _documentStore.OpenSession())
        {
            mapReduceResults =
                session.Query<MyIndex.MapReduceResult>(
                    MyIndex.INDEX_NAME)
                    .Customize(x => x.WaitForNonStaleResults()).ToArray();
        }
        Assert.That(mapReduceResults.Count, Is.EqualTo(1));
    }

    private void InitData()
    {
        var visitOne = new Visit
                           {
                               Id = "visits/64",
                               MetaData = new MetaData {CreatedDate = new DateTime(1975, 8, 6, 0, 14, 0)},
                               MediaSourceId = 1,
                           };
        var visitPageVersionOne = new VisitPageVersion
                                      {
                                          Id = "VisitPageVersions/123",
                                          MetaData = new MetaData {CreatedDate = new DateTime(1975, 8, 6, 0, 14, 0)},
                                          VisitId = "visits/64",
                                          Version = "1"
                                      };

        using (var session = _documentStore.OpenSession())
        {
            session.Store(visitOne);
            session.Store(visitPageVersionOne);
            session.SaveChanges();
        }
    }

    public class MyIndex :
        AbstractMultiMapIndexCreationTask
            <MyIndex.MapReduceResult>
    {
        public const string INDEX_NAME = "MyIndex";

        public override string IndexName
        {
            get { return INDEX_NAME; }
        }

        public class MapReduceResult
        {
            public string VisitId { get; set; }
            public int? MediaSourceId { get; set; }
            public string Version { get; set; }
            public int Count { get; set; }
        }

        public MyIndex()
        {
            AddMap<Visit>(
                visits =>
                from visit in visits
                select new
                           {
                               VisitId = visit.Id,
                               MediaSourceId = (int?) visit.MediaSourceId,
                               Version = (string) null,
                               Count = 1
                           });
            AddMap<VisitPageVersion>(
                visitPageVersions =>
                from visitPageVersion in visitPageVersions
                select new
                           {
                               VisitId = visitPageVersion.VisitId,
                               MediaSourceId = (int?) null,
                               Version = visitPageVersion.Version,
                               Count = 0
                           });
            Reduce =
                results =>
                from result in results
                group result by result.VisitId
                into g
                select
                    new
                        {
                            VisitId = g.Key,
                            MediaSourceId = (int?) g.Select(x => x.MediaSourceId).FirstOrDefault(),
                            Version = g.Select(x => x.Version).FirstOrDefault(),
                            Count = g.Sum(x => x.Count)
                        };
        }
    }
}

1 个答案:

答案 0 :(得分:0)

你不需要做任何事情就可以给予nullables特殊待遇。 RavenDB已经开始处理这个问题了。