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
)
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743883355a4523576.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