You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LinqToDB报错:投影类型ES_PRODUCT找不到关联键'Oid'

问题描述

以下代码可正常运行,能从表中查询记录并投影到新对象,正确获取结果:

var results98 =
    (from record in x.Psi.Psiproductparts
     from infoRecord in record.Programpressinforecords
     let p =
        new ES_WONPROGRAMPRESSINFORMATIONRECORD()
        {
            record_title = infoRecord.PpiTitle
        }
     select p.record_title).ToArray();

但下方代码执行失败:

var results97 =
    (from record in x.Psi.Psiproductparts
     let bar = 
         new ES_PRODUCT
         {
            p_product_programpressinformationrecords =
                from infoRecord in record
                    .Programpressinforecords
                select new ES_WONPROGRAMPRESSINFORMATIONRECORD()
                {
                    record_title = infoRecord.PpiTitle
                }
         }
    from infoRecord2 in bar.p_product_programpressinformationrecords
    select infoRecord2.record_title).ToArray();

报错信息:

LinqToDB.Linq.LinqException HResult=0x80131500 Message=Association key 'Oid' not found for type 'Linq2DbPostgresWon.ES_PRODUCT.

其中ES_PRODUCT仅为普通载体类,并非数据库表,定义如下:

class ES_PRODUCT
{
    public IEnumerable<ES_WONPROGRAMPRESSINFORMATIONRECORD>? p_product_programpressinformationrecords { get; set; }
}
问题原因

LinqToDB的查询解析逻辑在处理嵌套查询时,误将带有集合属性的ES_PRODUCT识别为需要数据库关联的实体类。它会尝试为这类类型查找默认的关联键(比如Oid),但ES_PRODUCT只是普通的数据传输对象(DTO),并没有定义对应的关联字段,因此抛出找不到关联键的错误。

解决办法

提供三种可行的解决思路:

1. 扁平化查询逻辑(推荐)

直接沿用第一个正常运行的代码结构,避免在查询中间构造包含集合属性的自定义类,让LinqToDB可以正常解析查询逻辑:

var results97 =
    (from record in x.Psi.Psiproductparts
     from infoRecord in record.Programpressinforecords
     select new ES_WONPROGRAMPRESSINFORMATIONRECORD()
     {
         record_title = infoRecord.PpiTitle
     }.record_title).ToArray();

2. 切换到内存查询构造载体类

如果必须使用ES_PRODUCT作为中间载体,可以通过AsEnumerable()将外层查询切换到内存中执行,避免LinqToDB解析ES_PRODUCT的关联逻辑:

var results97 =
    (from record in x.Psi.Psiproductparts.AsEnumerable()
     let bar = 
         new ES_PRODUCT
         {
            p_product_programpressinformationrecords =
                from infoRecord in record.Programpressinforecords
                select new ES_WONPROGRAMPRESSINFORMATIONRECORD()
                {
                    record_title = infoRecord.PpiTitle
                }
         }
    from infoRecord2 in bar.p_product_programpressinformationrecords
    select infoRecord2.record_title).ToArray();

注意:这种方式会将Psiproductparts的所有数据拉取到内存中,数据量较大时可能影响性能,需谨慎使用。

3. 标记类为非数据库表

给ES_PRODUCT添加LinqToDB的[NotTable]特性,明确告知框架该类不是数据库表,无需处理关联逻辑:

using LinqToDB.Mapping;

[NotTable]
class ES_PRODUCT
{
    public IEnumerable<ES_WONPROGRAMPRESSINFORMATIONRECORD>? p_product_programpressinformationrecords { get; set; }
}

修改后,原查询代码即可正常运行。

内容的提问来源于stack exchange,提问作者MrD at KookerellaLtd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 23:11:09