admin管理员组文章数量:1353636
Let's say I've got two tables Business
and Owner
. Business
would be the primary table and Owner
would link to that table. However, here's where it gets weird for me, and why I want to figure this out with Entity Framework Core.
Table Business
ID (int)
Name (varchar 50)
...
public class Business
{
public int ID { get; set; }
public string Name { get; set; }
// ...
}
Table Owner
ID (int)
Name (varchar 50)
PrimaryBusinessID (int)
SecondaryBusinessID (int)
IsActive (bit)
...
public class Owner
{
public int ID { get; set; }
public string Name { get; set; }
public int PrimaryBusinessID { get; set; }
public int? SecondaryBusinessID { get; set; }
public bool IsActive { get; set; }
// ...
}
In the SQL that already exists for this system, we're trying to find any active owners. And a business could have a primary or a secondary owner. However, this join is done on the Owner
side, not on the Business
side, which seems backwards to me... but this isn't a database schema that I can touch and modify, so I have to deal with what I have.
Given the above, I'm trying to create a relationship between the two of them to query out what Businesses are active. The only way to know is if they have a primary owner or a secondary owner that has the IsActive
flag set to True.
The SQL that's trying to do this right now is below:
SELECT DISTINCT B.ID, B.Name
FROM Business B
LEFT OUTER JOIN
(SELECT PrimaryBusinessID, SecondaryBusinessID
FROM Owner
WHERE IsActive = 1) AS O ON B.ID = O.PrimaryBusinessID
OR B.ID = O.SecondaryBusinessID
Again, while I think this SQL and schema should be updated and worked on, this is not something I can do. So I'm trying to stay as 'true' to what was written before and still get the same results through Entity Framework Core.
Let's say I've got two tables Business
and Owner
. Business
would be the primary table and Owner
would link to that table. However, here's where it gets weird for me, and why I want to figure this out with Entity Framework Core.
Table Business
ID (int)
Name (varchar 50)
...
public class Business
{
public int ID { get; set; }
public string Name { get; set; }
// ...
}
Table Owner
ID (int)
Name (varchar 50)
PrimaryBusinessID (int)
SecondaryBusinessID (int)
IsActive (bit)
...
public class Owner
{
public int ID { get; set; }
public string Name { get; set; }
public int PrimaryBusinessID { get; set; }
public int? SecondaryBusinessID { get; set; }
public bool IsActive { get; set; }
// ...
}
In the SQL that already exists for this system, we're trying to find any active owners. And a business could have a primary or a secondary owner. However, this join is done on the Owner
side, not on the Business
side, which seems backwards to me... but this isn't a database schema that I can touch and modify, so I have to deal with what I have.
Given the above, I'm trying to create a relationship between the two of them to query out what Businesses are active. The only way to know is if they have a primary owner or a secondary owner that has the IsActive
flag set to True.
The SQL that's trying to do this right now is below:
SELECT DISTINCT B.ID, B.Name
FROM Business B
LEFT OUTER JOIN
(SELECT PrimaryBusinessID, SecondaryBusinessID
FROM Owner
WHERE IsActive = 1) AS O ON B.ID = O.PrimaryBusinessID
OR B.ID = O.SecondaryBusinessID
Again, while I think this SQL and schema should be updated and worked on, this is not something I can do. So I'm trying to stay as 'true' to what was written before and still get the same results through Entity Framework Core.
Share Improve this question edited Apr 1 at 19:25 Thom A 96.2k11 gold badges61 silver badges95 bronze badges asked Apr 1 at 13:19 CrystalBlueCrystalBlue 1,8735 gold badges19 silver badges27 bronze badges 1 |2 Answers
Reset to default 2An exact copy of the SQL to Linq would be use from
and DefaultIfEmpty
var query = (
from b in db.Business
from o in db.Owner.Where(o =>
o.IsActive &&
(b.ID == o.PrimaryBusinessID || b.ID == O.SecondaryBusinessID)
).DefaultIfEmpty()
select b
).Distinct();
But the original query was wrong, as it won't actually filter it properly, since it's a LEFT JOIN
. It should have been an INNER JOIN
, and therefore you should remove .DefaultIfEmpty()
Moreover, there is no point joining if you don't want the results. You might as well just do an EXISTS
SELECT b.ID, b.Name
FROM Business B
WHERE EXISTS (SELECT 1
FROM Owner o
WHERE o.IsActive = 1
AND (b.ID = o.PrimaryBusinessID OR b.ID = o.SecondaryBusinessID)
);
Which becomes
var query = db.Business.Where(b =>
db.Owner.Any(o =>
o.IsActive &&
(b.ID == o.PrimaryBusinessID || b.ID == O.SecondaryBusinessID)
)
);
Alternatively, it's probably more efficient to use two separate checks
var query = db.Business.Where(b =>
db.Owner.Any(o =>
o.IsActive &&
b.ID == o.PrimaryBusinessID
) &&
db.Owner.Any(o =>
o.IsActive &&
b.ID == O.SecondaryBusinessID
)
);
To find businesses that do not have any owner, you can use following query with NOT EXISTS
:
SELECT DISTINCT B.ID, B.Name
FROM Business B
WHERE NOT EXISTS (
SELECT 1 FROM Owner
WHERE IsActive = 1
AND PrimaryBusinessID = B.ID
) AND NOT EXISTS (
SELECT 1 FROM Owner
WHERE IsActive = 1
AND SecondaryBusinessID = B.ID
)
本文标签: cRelationship between two tables on different key valuesStack Overflow
版权声明:本文标题:c# - Relationship between two tables on different key values - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743883355a2555605.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
DISTINCT
if you don't need those columns, you might as well use anEXISTS
? And if it's aLEFT JOIN
then you can elide the whole thing completely as it doesn't affect the results. – Charlieface Commented Apr 1 at 13:22