Eul*_*tor 4 linq-to-entities entity-framework left-join outer-join
在使用实体框架时,我已阅读了与在Linq to Entities(.NET 3.5)中实现等效的LEFT OUTER JOIN相关的所有帖子,但尚未找到解决以下问题的方法.
给出两个表,由下面的对象表示:
public class Foo
{
public int FooId; // primary key
public string Name;
}
public class Bar
{
public int BarId; // primary key
public int FooId; // foreign key
public string Desc;
}
Run Code Online (Sandbox Code Playgroud)
我需要创建一个Linq to Entities语句,它是以下SQL语句的EQUIVALENT.请注意,WHERE语句包含两个OR'd条件,这两个条件跨越两个表,并使用DISTINCT限定符.
SELECT DISTINCT
Foo.*
FROM
Foo
LEFT OUTER JOIN Bar ON Foo.FooId = Bar.FooId
WHERE
(Foo.Name = 'fooname' OR Bar.Desc = 'bardesc')
Run Code Online (Sandbox Code Playgroud)
我生成的Linq查询是通过实体框架实现的Linq到实体,并且(希望)生成一个要在服务器上执行的SQL语句.Linq to Entities不支持FirstOrDefault()扩展子句,因此LEFT OUTER JOIN的标准Linq语法将不起作用.
这是我的解决方案,但我无法做到以下任何一种情况:
1)生成一个结果集,其中包含由LEFT OUTER JOIN操作返回的一组Foo/Bar组合.
2)实现WHERE子句的等价物: WHERE (Foo.Name = 'fooname' OR Bar.Desc = 'bardesc')
private class JoinSet
{
public Foo Foo;
public IQueryable<Bar> Bars;
};
private class FooBar
{
public Foo Foo;
public Bar Bar;
};
IEnumerable<Foo> OuterJoinTest()
{
IQueryable<Foo> fooBaseQuery = dbContext.FooSet;
IQueryable<Bar> barBaseQuery = dbDontext.BarSet;
IQueryable<JoinSet> joinQuery =
from foo in fooBaseQuery
select new JoinSet
{
Foo = foo,
Bars = barBaseQuery.Where(bar => bar.FooId == foo.FooId)
};
// How do I generate a result set containing FooBar objects ?
// How or where do I insert the equivalent of: ?
// WHERE (Foo.Name = 'fooname' OR Bar.Description = 'bardesc')
IQueryable<Foo> resultQuery =
from joinSet in joinQuery
select joinSet.Foo;
resultQuery = resultQuery.Distinct();
return resultQuery.ToList();
}
Run Code Online (Sandbox Code Playgroud)
任何帮助,想法或建议将不胜感激.
EulerOperator
Adu*_*cci 11
private class FooBar
{
public Foo Foo { get; set; }
public Bar? Bar { get; set; }
}
var innerQuery = from foo in context.Foos
from bar in context.Bars
where foo.Name == 'fooname' || bar.Description == 'bardesc'
where foo.FooId == bar.FooId
select new FooBar { Foo = foo, Bar = bar };
var outerQuery = from foo in context.Foos
where foo.Name == 'fooname'
where !context.Bars.Any(b => b.FooId == foo.FooId)
select new FooBar { Foo = foo, Bar = null };
var leftouterjoinQuery = innerQuery.Union(outerQuery).Distinct();
Run Code Online (Sandbox Code Playgroud)
var query = (from foo in context.Foo
join b in context.Bar
on foo.FooId equals b.FooId into Bar
from bar in Bar.DefaultIfEmpty()
where foo.Name = 'fooname' || bar.Description = 'bardesc'
select new { foo, bar }).Distinct();
Run Code Online (Sandbox Code Playgroud)