使用 Union 时使用 DefaultIfEmpty 获取默认 class 值
Use DefaultIfEmpty to get default class values when using Union
我需要 return 一组基于元组值列表的 MyClass
。此元组值用于从数据库中获取正确的对象。
为了避免多次调用 db,我尝试使用 Union
构建查询,然后仅在调用 .ToList()
方法后从 db 获取所有数据。
在这种情况下,如果查询中没有结果,我需要 return 一个默认值对象。当我应用 DefaultIfEmpty
方法时,出现错误。这个想法是,如果我收到一个 List
的 15 个元组,我需要 return 15 个结果,如果没有结果,它们应该用内置的默认 Class
值填充。
public ISet<MyClass> Post([FromBody] IList<Tuple<string, string>> codesToFilter)
{
IEnumerable<MyClass> filteredObjectsByCodes = new List<MyClass>();
foreach (Tuple<string, string> tupleElement in codesToFilter)
{
//Class built based on parameters to be returned if there are no records in db
MyClass classDefaultValue = new MyClass(tupleElement.Item1,
"A default property string",
"Default text",
tupleElement.Item2);
var filteredObjects = (from entity in DatabaseContext.MyEntities
where (entity.Property1 == tupleElement.Item1 &&
entity.Property4== tupleElement.Item2)
select new MyClass
(
entity.Property1,
entity.Property2,
entity.Property3,
entity.Property4
)
).DefaultIfEmpty(classDefaultValue);
filteredObjectsByCodes = filteredObjectsByCodes.Union(filteredObjects);
}
var filteredObjectsResult = new HashSet<MyClass>((filteredObjectsByCodes.ToList()));
return filteredObjectsResult;
}
知道如何以优化的方式实现这一点吗?
也许您可以删除 DefaultIfEmpty 并稍后添加缺少的 MyClasses。
IEnumerable<MyClass> results = filteredObjectsByCodes.ToList();
var missing = codesToFilter
.Where(c => results.All(f => f.Property1 != c.Item1 && f.Property4 != c.Item2))
.Select(c => new MyClass(tupleElement.Item1.. );
results = results.Union(missing);
return new HashSet<MyClass>(results);
在调用 DefaultIfEmpty
之前调用 AsEnumerable
。这是一个首先在数据库端执行没有意义的操作。从DB中获取结果,如果为空,则让应用程序将默认项添加到序列中。
要避免在应用程序端执行 Union
,您需要做的就是在合并各种数据库查询后应用 AsEnumerable().DefaultIfEmpty(...)
调用。在聚合所有子查询之前不需要执行 DefaultIfEmpty
。
我需要 return 一组基于元组值列表的 MyClass
。此元组值用于从数据库中获取正确的对象。
为了避免多次调用 db,我尝试使用 Union
构建查询,然后仅在调用 .ToList()
方法后从 db 获取所有数据。
在这种情况下,如果查询中没有结果,我需要 return 一个默认值对象。当我应用 DefaultIfEmpty
方法时,出现错误。这个想法是,如果我收到一个 List
的 15 个元组,我需要 return 15 个结果,如果没有结果,它们应该用内置的默认 Class
值填充。
public ISet<MyClass> Post([FromBody] IList<Tuple<string, string>> codesToFilter)
{
IEnumerable<MyClass> filteredObjectsByCodes = new List<MyClass>();
foreach (Tuple<string, string> tupleElement in codesToFilter)
{
//Class built based on parameters to be returned if there are no records in db
MyClass classDefaultValue = new MyClass(tupleElement.Item1,
"A default property string",
"Default text",
tupleElement.Item2);
var filteredObjects = (from entity in DatabaseContext.MyEntities
where (entity.Property1 == tupleElement.Item1 &&
entity.Property4== tupleElement.Item2)
select new MyClass
(
entity.Property1,
entity.Property2,
entity.Property3,
entity.Property4
)
).DefaultIfEmpty(classDefaultValue);
filteredObjectsByCodes = filteredObjectsByCodes.Union(filteredObjects);
}
var filteredObjectsResult = new HashSet<MyClass>((filteredObjectsByCodes.ToList()));
return filteredObjectsResult;
}
知道如何以优化的方式实现这一点吗?
也许您可以删除 DefaultIfEmpty 并稍后添加缺少的 MyClasses。
IEnumerable<MyClass> results = filteredObjectsByCodes.ToList();
var missing = codesToFilter
.Where(c => results.All(f => f.Property1 != c.Item1 && f.Property4 != c.Item2))
.Select(c => new MyClass(tupleElement.Item1.. );
results = results.Union(missing);
return new HashSet<MyClass>(results);
在调用 DefaultIfEmpty
之前调用 AsEnumerable
。这是一个首先在数据库端执行没有意义的操作。从DB中获取结果,如果为空,则让应用程序将默认项添加到序列中。
要避免在应用程序端执行 Union
,您需要做的就是在合并各种数据库查询后应用 AsEnumerable().DefaultIfEmpty(...)
调用。在聚合所有子查询之前不需要执行 DefaultIfEmpty
。