鉴于以下类别:
public class Lookup
{
public string Code { get; set; }
public string Name { get; set; }
}
public class DocA
{
public string Id { get; set; }
public string Name { get; set; }
public Lookup Currency { get; set; }
}
public class ViewA // Simply a flattened version of the doc
{
public string Id { get; set; }
public string Name { get; set; }
public string CurrencyName { get; set; } // View just gets the name of the currency
}
我可以创建一个允许客户端查询视图的索引,如下所示:
public class A_View : AbstractIndexCreationTask<DocA, ViewA>
{
public A_View()
{
Map = docs => from doc in docs
select new ViewA
{
Id = doc.Id,
Name = doc.Name,
CurrencyName = doc.Currency.Name
};
Reduce = results => from result in results
group on new ViewA
{
Id = result.Id,
Name = result.Name,
CurrencyName = result.CurrencyName
} into g
select new ViewA
{
Id = g.Key.Id,
Name = g.Key.Name,
CurrencyName = g.Key.CurrencyName
};
}
}
这肯定有效并产生所需的视图结果,数据转换为客户端应用程序所需的结构。然而,它是不可行的冗长,将是一个维护噩梦,并且可能在所有冗余对象构造中效率相当低。
在给定文档集合(DocA)的情况下,是否有更简单的方法创建具有所需结构的索引(ViewA)?
更多信息 问题似乎是为了让索引保存转换结构(ViewA)中的数据,我们必须进行Reduce。似乎Reduce必须同时具有GROUP ON和SELECT才能按预期工作,因此以下内容无效:
INVALID REDUCE CLUUSE 1:
Reduce = results => from result in results
group on new ViewA
{
Id = result.Id,
Name = result.Name,
CurrencyName = result.CurrencyName
} into g
select g.Key;
这会产生:System.InvalidOperationException:变量初始化程序选择必须具有带对象创建表达式的lambda表达式
显然我们需要'选择新'。
INVALID REDUCE CLAUSE 2:
Reduce = results => from result in results
select new ViewA
{
Id = result.Id,
Name = result.Name,
CurrencyName = result.CurrencyName
};
此产品:System.InvalidCastException:无法将类型为“ICSharpCode.NRefactory.Ast.IdentifierExpression”的对象强制转换为“ICSharpCode.NRefactory.Ast.InvocationExpression”。
显然,我们还需要'新组'。
感谢您提供的任何帮助。
(注意:从构造函数调用中删除类型(ViewA)对上面的内容没有影响)
使用正确的方法更新
如下面答案中提到的Daniel的博客中所述,以下是此示例的正确方法:
public class A_View : AbstractIndexCreationTask<DocA, ViewA>
{
public A_View()
{
Map = docs => from doc in docs
select new ViewA
{
Id = doc.Id,
Name = doc.Name,
CurrencyName = doc.Currency.Name
};
// Top-level properties on ViewA that match those on DocA
// do not need to be stored in the index.
Store(x => x.CurrencyName, FieldStorage.Yes);
}
}
答案 0 :(得分:4)
一种解决方案,只需在Map中展平并配置索引以仅存储DocA中不存在的属性。
public class A_View : AbstractIndexCreationTask<DocA, ViewA>
{
public A_View()
{
Map = docs => from doc in docs
select new ViewA
{
Id = doc.Id,
Name = doc.Name,
CurrencyName = doc.Currency.Name
};
// Top-level properties on ViewA that match those on DocA
// do not need to be stored in the index.
Store(x => x.CurrencyName, FieldStorage.Yes);
}
}