给定以下对象结构:
public class Object
{
public string Id {get;set;}
public List<SubObject> SubObjects {get;set;}
}
public class SubObject {get;set;}
{
public string Id {get;set;}
public string Name {get;set;}
}
如何构造查询以返回Name.Contains("a")
我觉得它应该是直截了当的,但我真的很挣扎。
答案 0 :(得分:2)
简短的回答,你没有。 RavenDb中的文档是聚合根,您无法加载聚合根的一部分,只能加载整个根。因此,您可以获取包含Objects
的所有Subobjects
,其中包含'a'
的名称,但您无法自行获取子对象。如果需要单独获取它们,请将SubObjects设置为自己的文档。
答案 1 :(得分:2)
在根对象上,您需要存储子对象的ID。然后,在加载根对象时,需要在查询中使用Raven Include()功能。这将把所有subObject文档拉入会话。然后,您可以加载子对象。这是我一直在做的一个例子:
这是一个根对象:
public class Application : EntityBase
Application具有CustomVariableGroup类型的子对象。所以我需要在对象中存储ID(这就是RavenDB将保存的内容)。
public List<string> CustomVariableGroupIds { get; set; } // For RavenDB
实际的子对象仍然存储在根对象上,但不会以这种方式保存在Raven中:
[JsonIgnore] // We do not want RavenDB to serialize this.
public ObservableCollection<CustomVariableGroup> CustomVariableGroups
这就是设置,现在是Raven处理它的方式。 (忘掉ExecuteQuery()方法;这是我自己的,超出了这个问题的范围。)
这是获取根对象的调用。注意我们将ID拉入会话的Include():
public Application GetByName(string name)
{
return ExecuteQuery<Application>(() =>
{
Application application = QuerySingleResultAndSetEtag(session =>
session.Query<Application>()
.Include(x => x.CustomVariableGroupIds)
.Where(app => app.Name == name).FirstOrDefault())
as Application;
HydrateApplication(application);
return application;
});
}
以下是我们加载subObjects的方法:
public static void HydrateApplication(Application app)
{
if (app == null) { throw new ArgumentNullException("app"); }
if (app.CustomVariableGroupIds == null) { return; }
app.CustomVariableGroups = new ObservableCollection<CustomVariableGroup>();
foreach (string groupId in app.CustomVariableGroupIds)
{
app.CustomVariableGroups.Add(QuerySingleResultAndSetEtag(session => session.Load<CustomVariableGroup>(groupId)) as CustomVariableGroup);
}
}
最后,在保存根对象时,我确保保存子对象ID:
private static void SetCustomVariableGroupIds(Application application)
{
application.CustomVariableGroupIds = new List<string>();
if (application.CustomVariableGroups == null || application.CustomVariableGroups.Count < 1) { return; }
foreach (CustomVariableGroup group in application.CustomVariableGroups)
{
application.CustomVariableGroupIds.Add(group.Id);
}
}
希望有所帮助。这允许人们保持域模型“纯粹”IMO。实体可以保存对其他实体的引用,而不仅仅是其他实体的非规范化版本。
好的,并且实际回答你的问题......一旦你的文档被加载,你可以简单地使用LINQ来查询subObjects,因为现在它们实际上会在内存中。
答案 2 :(得分:1)
Session.Query<Object>.Where(x => x.SubObject.Any(a => a.Name.StartsWith("a"))).ToList();
我不确定Contains
是否有效,但这应该让你开始。