简体   繁体   English

EF Core,左外加入或条件

[英]EF Core, Left Outer Join With Or Condition

I want to write a EF query for SQL like this我想像这样为 SQL 编写一个 EF 查询

select *
from Table1 t1
left outer join t2 on (t1.id = t2.ParentId or t1.id2 = t2.ParentId2) 

So that I return ALL t1 rows with a match on either condition on t2, but return t1 if neither condition matches.所以我返回所有 t1 行,在 t2 的任一条件下都匹配,但如果两个条件都不匹配,则返回 t1。 If it was an AND condition, EF can support this, but for OR most people do it in the Where clause rather than the Join condition.如果它是 AND 条件,EF 可以支持这一点,但对于 OR,大多数人在 Where 子句而不是 Join 条件中执行此操作。 However if I do that, only the matched rows are returned, not the non matched rows in t1但是,如果我这样做,则只返回匹配的行,而不是 t1 中的不匹配行

Eg As an AND condition its easy to do例如,作为一个 AND 条件,它很容易做到

   var result = from t1 in db.Table1s
                join t2 in db.Table2s on new {t1.id, t1.id2} equals new {t2.parentId, t2.parentId2}
                     into t2join
                from t2 in t2join.DefaultIfEmpty() 

For illustration this can be written as a cross join but does not return the t1 rows with no match为了说明,这可以写为交叉连接,但不返回不匹配的 t1 行

   var result = from t1 in db.Table1s
                from t2 in db.Table2s
                where t1.id == t2.parentId || t1.id2 == t2.parentId2 || t}

So I need to use the first syntax, but how can I do that with an OR clause?所以我需要使用第一种语法,但是如何使用 OR 子句来做到这一点? So Ideally I want something like所以理想情况下,我想要类似的东西

 var result = from t1 in db.Table1s
                join t2 in db.Table2s on t1.id == t2.parentId || t1.id2 == t2.parentId2 
                     into t2join
                from t2 in t2join.DefaultIfEmpty() 

I see no way of achieving this with a normal LINQ to SQL query (happy to be proven wrong).我看不出用普通的 LINQ 到 SQL 查询来实现这一点(很高兴被证明是错误的)。 The only way round it I see is to call the direct SQL from EF and this is how I achieved that using FromSqlInterpolated我看到的唯一方法是直接从 EF 调用 SQL 这就是我使用 FromSqlInterpolated 实现的方法

First I need a new EF model to hold my result set, but I don't want a new table for this.首先,我需要一个新的 EF model 来保存我的结果集,但我不想要一个新表。 This is done by creating a DbSet for the ResultModel in my DbContext and then specified in the OnModelCreating, that it HasNoKey, and also map it to a null view, so not to create the table.这是通过在我的 DbContext 中为 ResultModel 创建一个 DbSet 然后在 OnModelCreating 中指定它 HasNoKey 以及 map 它到 null 视图来完成的,因此不要创建表。

 public DbSet<ResultModel> ResultModelSet{ get; set; }

 protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);     

            modelBuilder.Entity<ResultModel>().HasNoKey().ToView(null);
        }

Then in my query I can run the raw sql and map it back into this model然后在我的查询中,我可以将原始 sql 和 map 运行回这个 model

  var result= await db.ResultModelSet
                .FromSqlInterpolated($@"select t1.id, t1.ida, t2.ParentId, t2.ParentId2
                                     from Table1 t1
                                     left outer join t2 on 
                                             (t1.id = t2.ParentId or 
                                              t1.id2 = t2.ParentId2)
                                        ")
                .ToListAsync();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM