0

我需要返回一组MyClass基于元组值列表。此元组值用于从数据库中获取正确的对象。为了避免多次调用 db,我尝试使用 aUnion来构建查询,然后只调用一次.ToList()方法从 db 中获取所有数据。在这种情况下,如果查询中没有结果,我需要返回一个默认值对象。当我应用该DefaultIfEmpty方法时,我得到一个错误。这个想法是,如果我收到List15 个元组,我需要返回 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;
}

知道如何以优化的方式完成此任务吗?

4

2 回答 2

1

也许您可以删除 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);
于 2015-02-06T14:49:02.453 回答
0

调用AsEnumerable前调用DefaultIfEmpty。这是一个首先在数据库端执行的操作是没有意义的。从数据库中获取结果,如果为空,让应用程序将默认项添加到序列中。

为了避免Union在应用程序端执行,您需要做的就是AsEnumerable().DefaultIfEmpty(...)在联合各种数据库查询后应用调用。DefaultIfEmpty在聚合所有子查询之前无需执行 。

于 2015-02-06T15:17:16.127 回答