简体   繁体   English

Linq2DB EF核心联接表在循环中

[英]Linq2DB EF Core Join Tables In Loop

I am using linq2db.EntityFrameworkCore 我正在使用linq2db.EntityFrameworkCore

I need to join to DocumentMetadataValue table join to Document table dynamically. 我需要加入DocumentMetadataValue表,并动态加入Document表。

Left joined tables can be like DocumentMetadataValue_1, DocumentMetadataValue_5, DocumentMetadataValue_9, DocumentMetadataValue_11 etc. 左连接表可以像DocumentMetadataValue_1,DocumentMetadataValue_5,DocumentMetadataValue_9,DocumentMetadataValue_11等。

How do I achieve this using Linq2Db. 如何使用Linq2Db实现此目的。

Please find below code. 请找到下面的代码。 This is just to explain the problem. 这仅仅是为了解释问题。 So it doesn't work as it is the question. 所以这是行不通的,因为这是问题。

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;

If I understood what you want, you need to write something like that (pure linq2db, so don't forget to add ToLinqToDBTable calls): 如果我了解您想要的内容,则需要编写类似的内容(纯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();

result: 结果:

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'

I believe u actually need Inner join, below u can use 我相信您实际上需要内部加入,您可以在下面使用

/* DocumentMetadataValue_1, DocumentMetadataValue_5, DocumentMetadataValue_9, DocumentMetadataValue_11 */ / * 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();

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

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