如何让RavenDB与WCF数据服务一起工作?
我使用WCF数据服务5.3.0和反射数据提供程序。我的源数据存储在RavenDB中,因此我的所有查询都被延迟。所以,在应用OData筛选器之后,在结果返回到客户端之前,是否有一些方法可以为我的查询调用.ToList() 更新:我的数据模型属性声明如何让RavenDB与WCF数据服务一起工作?,wcf,wcf-data-services,ravendb,odata,Wcf,Wcf Data Services,Ravendb,Odata,我使用WCF数据服务5.3.0和反射数据提供程序。我的源数据存储在RavenDB中,因此我的所有查询都被延迟。所以,在应用OData筛选器之后,在结果返回到客户端之前,是否有一些方法可以为我的查询调用.ToList() 更新:我的数据模型属性声明 public IQueryable<PositionModel> Positions { get { using (var session = OLAPDocument
public IQueryable<PositionModel> Positions
{
get
{
using (var session = OLAPDocumentStore.OpenSession())
{
return session
.Query<ConsolidatedApplicationPosition>()
.Select(x => new PositionModel
{
ApplicationId = x.ApplicationId,
CategoryId = x.CategoryId,
ID = x.Id,
Platform = x.Platform,
Position = x.Position,
RegionalCode = x.RegionalCode,
Timestamp = x.Timestamp,
TopListId = x.TopListId
})
.AsQueryable();
}
}
}
好的,我必须去刷新我关于WCF数据服务工作原理的记忆。肖恩·维尔德茅斯有 主要问题是您试图使用
Select
语句转换查询客户端。当您返回一个IQueryable
时,它应该直接连接到linq提供程序——在本例中,是RavenDB查询的输出。您可以应用Where
和OrderBy
过滤器,但不能使用Select
语句进行投影。这打破了查询链
因此,如果要从数据库中的ConsolidatedApplicationPosition
对象投影到要返回到WCF数据服务的PositionModel
对象,则必须以另一种方式进行。以下是一些选项:
return session.Query<ConsolidatedApplicationPosition>()
.AsProjection<PositionModel>();
或者通过使用DataServiceKey
属性更改WCF的约定:
[DataContract, DataServiceKey("Id")]
public class PositionModel
{
[DataMember]
public int Id { get; set; }
...
}
public class YourIndex : AbstractIndexCreationTask<ConsolidatedApplicationPosition>
{
public YourIndex()
{
Map = docs =>
from doc in docs
select new
{
// You need to map any fields that you might query
// or sort on through the odata filters.
};
TransformResults = (database, docs) =>
from doc in docs
select new PositionModel
{
// if you need integer identifiers in your result,
// you'll have to split them from the doc key, like this:
ID = int.Parse(doc.Id.ToString().Split('/')[1]),
// otherwise, just do this:
ID = doc.Id,
// bring over all of your other fields as well
Platform = doc.Platform
... etc ...
};
}
}
公共类YourIndex:AbstractIndexCreationTask
{
公共索引()
{
Map=docs=>
从文档中的文档
选择新的
{
//您需要映射可能查询的任何字段
//或者通过odata过滤器进行排序。
};
TransformResults=(数据库、文档)=>
从文档中的文档
选择新的位置模型
{
//如果结果中需要整数标识符,
//您必须将它们从文档密钥中拆分,如下所示:
ID=int.Parse(doc.ID.ToString().Split('/')[1]),
//否则,只需执行以下操作:
ID=文件ID,
//把你所有的其他领域也带过来
平台=文件平台
等
};
}
}
索引就位后,将按如下方式进行查询:
return session.Query<PositionModel, YourIndex>();
返回session.Query();
使用任一选项,查询中都没有select语句,因此无需执行
ToList
或AsQueryable
。您只需将RavenDB linq提供程序的IQueryable
接口发送到WCF数据服务上下文中即可。OData需要一个IQueryable
,这是设计延迟的。如果您想要更具体的答案,请显示一些代码。使用一些源代码更新了问题。.AsQueryable()
在这里是多余的。你可以不说了。你的问题还有其他方面吗?我不知道你想做什么。什么不起作用?当前代码总是生成空列表,直到我调用.ToList()。同样值得注意的是,他们正在为RavenDB 2.5(尚未发布)将转换与索引分离。这将允许您对动态索引进行转换,而不必创建静态索引。谢谢玩具的回复。它非常有用。但是我的问题是不同的(更新的假设)@JiříGluškov-我读了你的更新,但那不是真的。一个空的lucene查询返回所有的数据。这非常简单,我是用Fiddler发现的。我还发现,在对RavenDB服务器的请求中,如果查询参数不为空,则响应是正确的。@JiříGluškov-仔细阅读我的答案。这是因为您正在执行的Select
操作中断了查询。
public class YourIndex : AbstractIndexCreationTask<ConsolidatedApplicationPosition>
{
public YourIndex()
{
Map = docs =>
from doc in docs
select new
{
// You need to map any fields that you might query
// or sort on through the odata filters.
};
TransformResults = (database, docs) =>
from doc in docs
select new PositionModel
{
// if you need integer identifiers in your result,
// you'll have to split them from the doc key, like this:
ID = int.Parse(doc.Id.ToString().Split('/')[1]),
// otherwise, just do this:
ID = doc.Id,
// bring over all of your other fields as well
Platform = doc.Platform
... etc ...
};
}
}
return session.Query<PositionModel, YourIndex>();