有条件的包含在linq中的实体?

conditional entity-framework include linq

我觉得以下应该是可能的我只是不确定采取什么方法。

我想要做的是使用include方法来塑造我的结果,即定义沿着对象图遍历的距离。但是......我希望这种遍历是有条件的。

something like...

dealerships
    .include( d => d.parts.where(p => p.price < 100.00))
    .include( d => d.parts.suppliers.where(s => s.country == "brazil"));

我知道这不是有效的linq,事实上,它是非常错误的,但实质上我正在寻找一些方法来构建一个表达树,它将返回形状结果,相当于......

select *
from dealerships as d
outer join parts as p on d.dealerid = p.dealerid
    and p.price < 100.00
outer join suppliers as s on p.partid = s.partid
    and s.country = 'brazil'

重点是加入条件。

我觉得这对esql来说是相当直接的,但我最喜欢的是动态构建表达式树。

一如既往,感谢任何建议或指导

一般承认的答案

这应该做的伎俩:

using (TestEntities db = new TestEntities())
{
    var query = from d in db.Dealership
                select new
                {
                    Dealer = d,
                    Parts = d.Part.Where
                    (
                        p => p.Price < 100.0 
                             && p.Supplier.Country == "Brazil"
                    ),
                    Suppliers = d.Part.Select(p => p.Supplier)
                };

    var dealers = query.ToArray().Select(o => o.Dealer);
    foreach (var dealer in dealers)
    {
        Console.WriteLine(dealer.Name);
        foreach (var part in dealer.Part)
        {
            Console.WriteLine("  " + part.PartId + ", " + part.Price);
            Console.WriteLine
                (
                "  " 
                + part.Supplier.Name 
                + ", " 
                + part.Supplier.Country
                );
        }
    }
}

此代码将为您提供经销商列表,每个经销商都包含已过滤的部件列表。每个部分都引用了供应商。有趣的是,您必须以所示方式在select中创建匿名类型。否则,经销商对象的Part属性将为空。

此外,您必须在从查询中选择经销商之前执行SQL语句。否则,经销商的Part属性将再次为空。这就是我将ToArray()调用放在以下行中的原因:

var dealers = query.ToArray().Select(o => o.Dealer);

但我同意Darren的观点,这可能不是您图书馆用户所期望的。


热门答案

你确定这是你想要的吗?我问的唯一原因是,一旦您在经销商的零件上添加过滤器,您的结果就不再是经销商。您处理的特殊对象在很大程度上非常接近经销商(具有相同的属性),但“部件”属性的含义是不同的。它不是经销商和零件之间的关系,而是过滤关系。

换句话说,如果我从你的结果中抽出经销商并传递给我写的方法,然后在我的方法中我打电话:

var count = dealership.Parts.Count();

我期待得到零件,而不是价格低于100美元的巴西过滤零件。

如果您不使用经销商对象传递过滤后的数据,则变得非常容易。它变得如此简单:

    var query = from d in dealerships
               select new { DealershipName = d.Name, 
CheapBrazilProducts = dealership.Parts.Where(d => d.parts.Any(p => p.price < 100.00) || d.parts.suppliers.Any(s => s.country == "brazil")) };

如果我只是像你要求的那样得到过滤后的集合,我可能会使用上面提到的技术,然后使用像Automapper这样的工具将过滤后的结果从我的匿名类复制到真正的类。它不是非常优雅,但它应该工作。

我希望有所帮助!这是一个有趣的问题。




许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因