【问题标题】:Linq2DB EF Core Join Tables In LoopLinq2DB EF Core 循环连接表
【发布时间】:2019-07-13 18:51:34
【问题描述】:

我正在使用linq2db.EntityFrameworkCore

我需要动态加入 DocumentMetadataValue 表加入 Document 表。

左连接表可以是 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;

【问题讨论】:

    标签: c# entity-framework linq entity-framework-core linq2db


    【解决方案1】:

    如果我明白你想要什么,你需要编写类似的东西(纯 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'
    

    【讨论】:

    • 这解决了我的问题。所以只是想确认一下,没有投影类是没有办法的吗?
    • Projection 的角色将其分类以确保所有构建步骤的查询具有相同的类型。如果您不想显式添加新类,可以将其替换为匿名类型:initial select: new { doc = d, field1 = (DocumentField)null, field2 = (DocumentField)null, field3 = (DocumentField)null }select in join: new { d.doc, field1 = f, d.field2, d.field3 }。如果你不这样做 - 你将注定要手动为查询中的所有表达式编写生成逻辑。
    【解决方案2】:

    我相信你确实需要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();
    

    【讨论】:

    • 我需要这些循环连接。因为它不固定哪些连接将在那里。所以这些连接可以更少或更多。 1,5,9,11 只是示例表。它们可以是任何东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-13
    • 2018-10-10
    • 1970-01-01
    • 2019-03-27
    • 2017-12-21
    • 2018-07-09
    相关资源
    最近更新 更多