如何筛选可选字段
how to filter for an optional field
我有一个解决方案class:
public class Solution{
public bool? IsTemplate{get;set;}
public string createdBy{get;set;}
}
一些文档将 IsTemplate 字段设置为 true 或 false,很多文档没有。
如何获得将其设置为 false 的解决方案以及根本没有该字段的解决方案(遗留文档)?
我尝试通过 IsTemplate 为 null、false、null 或 false 进行过滤,但我从未得到没有 IsTemplate 字段的解决方案。
我必须工作的唯一方法如下,但它丑陋得要命。
using (IDocumentSession session = DocumentStoreHolder.Store.OpenSession())
{
var ret= session.Query<Solution>().Where(x =>
x.createdBy.Equals(owner)) //an user's solutions
.ToList()
.Where(s => s.IsTemplate == null || s.IsTemplate == false)
.ToList();
return ret;
}
假设第一个 ToList
被使用,因为这个 "document store" 提供的 IQueryable
实现出于某种原因不支持您的查询,您不能做更多。
我建议:
- 与提供商一起打开错误报告以实现所需的功能,或者如果您有权访问代码库则自行添加。
- 同时,使用
AsEnumerable
而不是 ToList
以便在继续之前不会缓冲整个数据集。
Where
子句看起来相当简单。如果您的应用程序在 属性 不存在和它为假之间没有语义差异(在您的描述中听起来像它),我会考虑将不存在条件映射到假条件并使用不存在的目标数据结构' 不允许为 nullable IsTemplate
.
using (IDocumentSession session = DocumentStoreHolder.Store.OpenSession())
{
return session.Query<Solution>()
.Where(x => x.createdBy.Equals(owner))
.AsEnumerable()
.Select(s => new {
IsTemplate = s.IsTemplate ?? false,
CreatedBy = s.CreatedBy })
.ToList();
}
注意生成的对象是匿名的,我们正在返回它;这使我们无法使用类型良好的方法签名。因此,我肯定会定义另一个Solution
class。
您可以看到设计自然出现:您现在有两种 Solution
类型。一个用于域,由应用程序使用并且根本不关心遗留条件,如 "IsTemplate" 为空(从应用程序的角度来看它永远不会),另一个仅用于粘合过渡期间的遗留条件。确保对它们进行组织并适当命名,以便清楚它们的用途(利用 .NET 命名空间,这就是它们的长处!)。
您需要创建一个索引来查看缺失的 属性:
from x in docs.Solutions
select new
{
IsTemplate = x.IsTemplate == true // if this is null, will return false
}
然后查询。
var ret = session.Query<Solution>()
.Where(x => x.createdBy.Equals(owner)
&& (!x.IsTemplate.HasValue || x.IsTemplate.Value == false))
.ToList();
我有一个解决方案class:
public class Solution{
public bool? IsTemplate{get;set;}
public string createdBy{get;set;}
}
一些文档将 IsTemplate 字段设置为 true 或 false,很多文档没有。
如何获得将其设置为 false 的解决方案以及根本没有该字段的解决方案(遗留文档)?
我尝试通过 IsTemplate 为 null、false、null 或 false 进行过滤,但我从未得到没有 IsTemplate 字段的解决方案。 我必须工作的唯一方法如下,但它丑陋得要命。
using (IDocumentSession session = DocumentStoreHolder.Store.OpenSession())
{
var ret= session.Query<Solution>().Where(x =>
x.createdBy.Equals(owner)) //an user's solutions
.ToList()
.Where(s => s.IsTemplate == null || s.IsTemplate == false)
.ToList();
return ret;
}
假设第一个 ToList
被使用,因为这个 "document store" 提供的 IQueryable
实现出于某种原因不支持您的查询,您不能做更多。
我建议:
- 与提供商一起打开错误报告以实现所需的功能,或者如果您有权访问代码库则自行添加。
- 同时,使用
AsEnumerable
而不是ToList
以便在继续之前不会缓冲整个数据集。
Where
子句看起来相当简单。如果您的应用程序在 属性 不存在和它为假之间没有语义差异(在您的描述中听起来像它),我会考虑将不存在条件映射到假条件并使用不存在的目标数据结构' 不允许为 nullable IsTemplate
.
using (IDocumentSession session = DocumentStoreHolder.Store.OpenSession())
{
return session.Query<Solution>()
.Where(x => x.createdBy.Equals(owner))
.AsEnumerable()
.Select(s => new {
IsTemplate = s.IsTemplate ?? false,
CreatedBy = s.CreatedBy })
.ToList();
}
注意生成的对象是匿名的,我们正在返回它;这使我们无法使用类型良好的方法签名。因此,我肯定会定义另一个Solution
class。
您可以看到设计自然出现:您现在有两种 Solution
类型。一个用于域,由应用程序使用并且根本不关心遗留条件,如 "IsTemplate" 为空(从应用程序的角度来看它永远不会),另一个仅用于粘合过渡期间的遗留条件。确保对它们进行组织并适当命名,以便清楚它们的用途(利用 .NET 命名空间,这就是它们的长处!)。
您需要创建一个索引来查看缺失的 属性:
from x in docs.Solutions
select new
{
IsTemplate = x.IsTemplate == true // if this is null, will return false
}
然后查询。
var ret = session.Query<Solution>()
.Where(x => x.createdBy.Equals(owner)
&& (!x.IsTemplate.HasValue || x.IsTemplate.Value == false))
.ToList();