1

我希望能够重用索引中的一些转换表达式,以便当文档已经可用时,我可以在我的服务层中执行相同的转换。

例如,无论是通过查询还是通过在服务层转换现有文档,我都想生成一个具有这种形状的 ViewModel 对象:

public class ClientBrief
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }
    // ellided
}

从此文档模型:

public class Client
{
    public int Id { get; private set; }
    public CompleteName Name { get; private set; }
    public Dictionary<EmailAddressKey, EmailAddress> Emails { get; private set; }
    // ellided
}

public class CompleteName
{
    public string Title { get; set; }
    public string GivenName { get; set; }
    public string MiddleName { get; set; }
    public string Initials { get; set; }
    public string Surname { get; set; }
    public string Suffix { get; set; }
    public string FullName { get; set; }
}

public enum EmailAddressKey
{
    EmailAddress1,
    EmailAddress2,
    EmailAddress3
}

public class EmailAddress
{
    public string Address { get; set; }
    public string Name { get; set; }
    public string RoutingType { get; set; }
}

我有一个表达式可以将完整的 Client 文档转换为 ClientBrief 视图模型:

    static Expression<Func<IClientSideDatabase, Client, ClientBrief>> ClientBrief = (db, client) =>
        new ClientBrief
        {
            Id = client.Id,
            FullName = client.Name.FullName,
            Email = client.Emails.Select(x => x.Value.Address).FirstOrDefault()
            // ellided
        };

然后使用表达式访问者对该表达式进行操作,以便将其用作索引 (Client_Search) 的 TransformResults 属性,该属性在应用程序启动时生成后,在 Raven Studio 中具有以下定义:

地图:

docs.Clients.Select(client => new {
    Query = new object[] {
        client.Name.FullName,
        client.Emails.SelectMany(x => x.Value.Address.Split(new char[] {
            '@'
        })) // ellided
    }
})

Query分析该字段。)

转换:

results.Select(result => new {
    result = result,
    client = Database.Load(result.Id.ToString())
}).Select(this0 => new {
    Id = this0.client.__document_id,
    FullName = this0.client.Name.FullName,
    Email = DynamicEnumerable.FirstOrDefault(this0.client.Emails.Select(x => x.Value.Address))
})

但是,当我已经有一个客户端文档时,用于创建索引的转换表达式也可以在本地服务层中使用:

var brief = ClientBrief.Compile().Invoke(null, client);

它允许我只需要一段代码来理解从 Client 到 ClientBrief 的映射,无论该代码是在数据库中运行还是在客户端应用程序中运行。一切似乎都正常,除了查询结果的 ID 都是0.

如何在查询中正确填充 Id 属性(整数)?

我在这里阅读了许多类似的问题,但建议的答案似乎都不起作用。(将 Id 从整数更改为字符串不是一种选择。)

4

1 回答 1

0

我很难完全遵循您的示例,真正深入研究此问题的最佳方法是使用失败的独立单元测试。

尽管如此,让我们看看我是否可以提取出重要的部分。

在转换中,您有两个使用 id 的区域:

...
client = Database.Load(result.Id.ToString())
...
Id = this0.client.__document_id,
...

第一result.Id行和Id =第二行中的 the 应该是整数。

需要一个字符串文档键,这Database.Load()也是您在__document_id.

混淆来自 Raven 的文档、代码和示例,它们都交替使用术语idkey,但只有在使用字符串标识符时才会如此。当您使用非字符串标识符时,例如 ints 或 guids,id可能是123,但文档键仍然是clients/123

所以试着改变你的变换,让它翻译:

...
client = Database.Load("clients/" + result.Id)
...
Id = int.Parse(this0.client.__document_id.Split("/")[1]),
...

...或任何与 c# 等效的 linq 形式。

于 2013-01-18T00:13:30.963 回答