通过带有Where子句的实体框架通过Linq To Entities进行左外连接

发布于 2024-10-25 19:35:42 字数 2130 浏览 7 评论 0原文

我已阅读与使用实体框架时在 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;
    }

我需要创建一个 Linq to Entities 语句,该语句与以下 SQL 语句等效。请注意,WHERE 语句包含两个跨越两个表的 OR 条件,以及 DISTINCT 限定符的使用。

SELECT DISTINCT
    Foo.*
FROM
    Foo
    LEFT OUTER JOIN Bar ON Foo.FooId = Bar.FooId
WHERE
    (Foo.Name = 'fooname' OR Bar.Desc = 'bardesc')

我生成的 Linq 查询是通过实体框架的 Linq to Entities,并且(希望)生成要在服务器上执行的单个 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();
    }

任何帮助、想法或建议将不胜感激。

欧拉算子

I have read all the posts related to implementing the equivalent of a LEFT OUTER JOIN in Linq to Entities (.NET 3.5) when using the Entity Framework, but have yet to find a solution to the following problem.

Given two tables, represented by the objects below:

    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;
    }

I need to create a Linq to Entities statement which is the EQUIVALENT of the following SQL statement. Note that the WHERE statement contains two OR'd conditions which span both tables, and the use of the DISTINCT qualifier.

SELECT DISTINCT
    Foo.*
FROM
    Foo
    LEFT OUTER JOIN Bar ON Foo.FooId = Bar.FooId
WHERE
    (Foo.Name = 'fooname' OR Bar.Desc = 'bardesc')

The Linq query that I am generating is Linq to Entities via the Entity Framework, and will (hopefully) generate a single SQL statement to be executed on the server. Linq to Entities does not support the FirstOrDefault() extension clause, so the standard Linq syntax for LEFT OUTER JOINs will not work.

Here is the solution that I have SO FAR, but I am unable to do either of the following:

1) Generate a result set which contains the set of Foo/Bar combinations that would be returned by the LEFT OUTER JOIN operation.

2) Implement the equivalent of the WHERE clause: 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();
    }

Any help, ideas or suggestions would be appreciated.

EulerOperator

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白衬杉格子梦 2024-11-01 19:35:42

.NET 3.5

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();

.NET 4.0

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();

.NET 3.5

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();

.NET 4.0

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文