Linq2DB EF Core 在循环中加入表
Linq2DB EF Core Join Tables In Loop
我正在使用linq2db.EntityFrameworkCore
我需要加入 DocumentMetadataValue table 动态加入 Document table。
左连接 tables 可以像 DocumentMetadataValue_1、DocumentMetadataValue_5、DocumentMetadataValue_9、DocumentMetadataValue_11 等
如何使用 Linq2Db 实现此目的。
请查找以下代码。这只是为了说明问题。所以它不起作用,因为它是问题。
var query2 = from p in dbContext.Document
foreach (JObject childRule in queryRule.rules)
{
ChildRule rule = childRule.ToObject<ChildRule>();
string DocumentFieldTable = string.Format("DocumentField_{0}", rule.id);
//Here I need left join to query2.
from op in projectContext.Set<DocumentMetadataValue>().ToLinqToDBTable().TableName(DocumentFieldTable).LeftJoin(op => op.DocumentId == p.Id);
}
//After above selection I will apply where clause here and will select p from query2.
select p;
我相信你确实需要Inner join,下面你可以使用
/* DocumentMetadataValue_1, DocumentMetadataValue_5, DocumentMetadataValue_9, DocumentMetadataValue_11 */
var query2 = (from doc1 in dbContext.Document.DocumentMetadataValue_1
join doc5 in dbContext.Document.DocumentMetadataValue_5
on doc1.id equals doc5.id
join doc9 in dbContext.Document.DocumentMetadataValue_9
on doc5.id equals doc9.id
join doc11 in dbContext.Document.DocumentMetadataValue_11
on doc5.id equals doc11.id).ToList();
如果我明白你想要什么,你需要写类似的东西(纯 linq2db,所以不要忘记添加 ToLinqToDBTable
调用):
// define typed projection to include all possible joined tables
// otherwise you will need to write complex logic to build expressions
class Projection
{
public Document doc { get; set; }
public DocumentField field1 { get; set; }
public DocumentField field2 { get; set; }
public DocumentField field3 { get; set; }
}
// initial query typed as IQueryable<Projection>
var query = db.GetTable<Document>().Select(d => new Projection() { doc = d });
// select required joins (replace it with your query rules logic)
var with1 = true;
var with2 = false;
var with3 = true;
// add requested joins, note how we copy records
// from previous query to new projection
if (with1)
query = query.LeftJoin(
db.GetTable<DocumentField>().TableName("field_1"),
(d, f) => d.doc.Id == f.DocumentId,
(d, f) => new Projection () { doc = d.doc, field1 = f });
if (with2)
query = query.LeftJoin(
db.GetTable<DocumentField>().TableName("field_2"),
(d, f) => d.doc.Id == f.DocumentId,
(d, f) => new Projection() { doc = d.doc, field1 = d.field1, field2 = f });
if (with3)
query = query.LeftJoin(
db.GetTable<DocumentField>().TableName("field_3"),
(d, f) => d.doc.Id == f.DocumentId,
(d, f) => new Projection() { doc = d.doc, field1 = d.field1, field2 = d.field2, field3 = f });
// add filters
if (with1)
query = query.Where(r => r.field1.FilterMe == "test1");
if (with2)
query = query.Where(r => r.field2.FilterMe == "test2");
if (with3)
query = query.Where(r => r.field3.FilterMe == "test3");
// select only documents
query.Select(r => r.doc).ToArray();
结果:
SELECT
[d].[Id]
FROM
[Document] [d]
LEFT JOIN [field_1] [f_1] ON [d].[Id] = [f_1].[DocumentId]
LEFT JOIN [field_3] [f_2] ON [d].[Id] = [f_2].[DocumentId]
WHERE
[f_1].[FilterMe] = N'test1' AND [f_2].[FilterMe] = N'test3'
我正在使用linq2db.EntityFrameworkCore
我需要加入 DocumentMetadataValue table 动态加入 Document table。
左连接 tables 可以像 DocumentMetadataValue_1、DocumentMetadataValue_5、DocumentMetadataValue_9、DocumentMetadataValue_11 等
如何使用 Linq2Db 实现此目的。
请查找以下代码。这只是为了说明问题。所以它不起作用,因为它是问题。
var query2 = from p in dbContext.Document
foreach (JObject childRule in queryRule.rules)
{
ChildRule rule = childRule.ToObject<ChildRule>();
string DocumentFieldTable = string.Format("DocumentField_{0}", rule.id);
//Here I need left join to query2.
from op in projectContext.Set<DocumentMetadataValue>().ToLinqToDBTable().TableName(DocumentFieldTable).LeftJoin(op => op.DocumentId == p.Id);
}
//After above selection I will apply where clause here and will select p from query2.
select p;
我相信你确实需要Inner join,下面你可以使用
/* DocumentMetadataValue_1, DocumentMetadataValue_5, DocumentMetadataValue_9, DocumentMetadataValue_11 */
var query2 = (from doc1 in dbContext.Document.DocumentMetadataValue_1
join doc5 in dbContext.Document.DocumentMetadataValue_5
on doc1.id equals doc5.id
join doc9 in dbContext.Document.DocumentMetadataValue_9
on doc5.id equals doc9.id
join doc11 in dbContext.Document.DocumentMetadataValue_11
on doc5.id equals doc11.id).ToList();
如果我明白你想要什么,你需要写类似的东西(纯 linq2db,所以不要忘记添加 ToLinqToDBTable
调用):
// define typed projection to include all possible joined tables
// otherwise you will need to write complex logic to build expressions
class Projection
{
public Document doc { get; set; }
public DocumentField field1 { get; set; }
public DocumentField field2 { get; set; }
public DocumentField field3 { get; set; }
}
// initial query typed as IQueryable<Projection>
var query = db.GetTable<Document>().Select(d => new Projection() { doc = d });
// select required joins (replace it with your query rules logic)
var with1 = true;
var with2 = false;
var with3 = true;
// add requested joins, note how we copy records
// from previous query to new projection
if (with1)
query = query.LeftJoin(
db.GetTable<DocumentField>().TableName("field_1"),
(d, f) => d.doc.Id == f.DocumentId,
(d, f) => new Projection () { doc = d.doc, field1 = f });
if (with2)
query = query.LeftJoin(
db.GetTable<DocumentField>().TableName("field_2"),
(d, f) => d.doc.Id == f.DocumentId,
(d, f) => new Projection() { doc = d.doc, field1 = d.field1, field2 = f });
if (with3)
query = query.LeftJoin(
db.GetTable<DocumentField>().TableName("field_3"),
(d, f) => d.doc.Id == f.DocumentId,
(d, f) => new Projection() { doc = d.doc, field1 = d.field1, field2 = d.field2, field3 = f });
// add filters
if (with1)
query = query.Where(r => r.field1.FilterMe == "test1");
if (with2)
query = query.Where(r => r.field2.FilterMe == "test2");
if (with3)
query = query.Where(r => r.field3.FilterMe == "test3");
// select only documents
query.Select(r => r.doc).ToArray();
结果:
SELECT
[d].[Id]
FROM
[Document] [d]
LEFT JOIN [field_1] [f_1] ON [d].[Id] = [f_1].[DocumentId]
LEFT JOIN [field_3] [f_2] ON [d].[Id] = [f_2].[DocumentId]
WHERE
[f_1].[FilterMe] = N'test1' AND [f_2].[FilterMe] = N'test3'