我希望能够从索引中重用一些转换表达式,这样当文档可用时我可以在服务层中执行相同的转换。
例如,无论是通过查询还是通过转换服务层的现有文档,我都希望生成具有以下形状的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; }
}
我有一个表达式可以将完整的客户端文档转换为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从整数更改为字符串不是一种选择。)
答案 0 :(得分:0)
我很难完全跟踪你的样本,真正最好的方法是使用失败的自包含单元测试。
尽管如此,让我们看看能否取出重要的一些内容。
在转换中,您有两个使用id的区域:
...
client = Database.Load(result.Id.ToString())
...
Id = this0.client.__document_id,
...
第一行中的result.Id
和第二行中的Id =
应为整数。
Database.Load()
需要一个字符串文档密钥,这也是您在__document_id
中看到的内容。
Raven的文档,代码和示例的混淆都是可以互换地使用术语 id 和 key ,但这只是 时才是真的你使用字符串标识符。当您使用非字符串标识符(例如int或guid)时, id 可能为123
,但文档密钥仍为clients/123
。
因此,请尝试更改转换,以便进行翻译:
...
client = Database.Load("clients/" + result.Id)
...
Id = int.Parse(this0.client.__document_id.Split("/")[1]),
...
......或者c#等效的linq形式。