英文:
Linq query with optional join on table using .NET, LinqToDB & Postgresql
问题
以下是要翻译的内容:
What I want to accomplish;
A scout can create reports. The scout is the creator of the report.
We display the reports that this scout has created in a table.
The very same scout can be given access to a report that someone else has created.
All reports that this scout has access to should be displayed in the same table.
Tech stack
.NET 7 (LinqToDB), Postgresql
Database structure:
Table 1; "Reports".
Columns; Id, CreatedBy
Table 2; "ReportAccess"
Columns; ReportId, ScoutId
The linq query
Here's a sample of how I can get those reports that I have been given access to;
var query = from p in db.Reports
join c in db.ReportAccess on p.Id equals c.ReportId
where c.ScoutId == scoutId
select p;
and here's a sample of how I can get those reports that I have created;
var query = from p in db.Reports
where c.CreatedBy == scoutId
select p;
The question
How does one merge the two linq queries with an OR clause so only one query is made towards the db? I want to be able to use paging (take/skip) functionality, therefore the need of a single query.
I've tried to find examples without any luck.
I understand that I should probably start by creating an SQL query that later is transformed into linq syntax. I am not aware of how to create the SQL query.
英文:
What I want to accomplish;
A scout can create reports. The scout is the creator of the report.
We display the reports that this scout has created in a table.
The very same scout can be given access to a report that someone else has created.
All reports that this scout has access to should be displayed in the same table.
Tech stack
.NET 7 (LinqToDB), Postgresql
Database structure:
Table 1; "Reports".
Columns; Id, CreatedBy
Table 2; "ReportAccess"
Columns; ReportId, ScoutId
The linq query
Here's a sample of how I can get those reports that I have been given access to;
var query = from p in db.Reports
join c in db.ReportAccess on p.Id equals c.ReportId
where c.ScoutId == scoutId
select p;
and here's a sample of how I can get those reports that I have created;
var query = from p in db.Reports
where c.CreatedBy == scoutId
select p;
The question
How does one merge the two linq queries with an OR clause so only one query is made towards the db? I want to be able to use paging (take/skip) functionality, therefore the need of a single query.
I've tried to find examples without any luck.
I understand that I should probably start by creating an SQL query that later is transformed into linq syntax. I am not aware of how to create the SQL query.
答案1
得分: 1
你可以使用左连接(LEFT JOIN)来执行这样的查询:
var query =
from p in db.Reports
from c in db.ReportAccess
.Where(c => c.ReportId == p.Id && c.ScoutId == scoutId)
.DefaultIfEmpty()
where c != null || c.CreatedBy == scoutId
select p;
或者使用 Any
运算符。但要确保执行计划不会变得更差:
var query =
from p in db.Reports
where c.CreatedBy == scoutId ||
db.ReportAccess.Any(c => c.ReportId == p.Id && c.ScoutId == scoutId)
select p;
英文:
You can use LEFT JOIN for such query:
var query =
from p in db.Reports
from c in db.ReportAccess
.Where(c => c.ReportId == p.Id && c.ScoutId == scoutId)
.DefaultIfEmpty()
where c != null || c.CreatedBy == scoutId
select p;
Or Any
operator. But ensure that execution plan is not worse:
var query =
from p in db.Reports
where c.CreatedBy == scoutId ||
db.ReportAccess.Any(c => c.ReportId == p.Id && c.ScoutId == scoutId)
select p;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论