gpt4 book ai didi

c# - foreach 循环在具有多条记录的 Linq 查询后仅返回第一条记录

转载 作者:行者123 更新时间:2023-11-30 16:18:12 25 4
gpt4 key购买 nike

我有一个针对第三方提供的数据库运行的 Linq2SQL 查询。查询的主要部分如下所示:

         var valuationQuery =
from v in context.Valuations
where v.ModelId == QualifiedModelId.ModelId
&& v.QualifyModelId == QualifiedModelId.Qualifier
&& v.LanguageCode == QualifiedModelId.LanguageCode
&& v.Edition == Data.Meta.Edition.CurrentEdition.Date
&& v.RegDate == yearReg.RegistrationDate
&& v.ValTypeDescription == "Normal"
&& v.MileageBandID == MileageBand

当我用 foreach 循环围绕它时,它会工作还是失败取决于最后的选择。当 select 像这样指定所有字段时...

            select new
{
v.Value1,
v.Value2,
v.Value3,
... snip ...
v.Value14,
v.Value15,
v.ValueTypeID
};

...它正常工作。当我执行以下操作时,循环迭代了正确的次数,但每次都返回第一条记录:

            select v;

我希望能够在不指定名称的情况下选择所有字段,以防供应商添加更多字段(它们实际上被称为“Value1”到“Value15”),这意味着我可以在我的代码中更改一个常量并更新DBML 和所有相关代码将从正确数量的字段中查找。这个查询(和类似的查询)在不同的地方使用,所以我正在寻找 future 最省力的查询!

我已经运行了 SQL Profiler 以确保正在运行的查询返回正确的结果,而且确实如此。

foreach 循环是这样的(Convert 是由于设计非常糟糕的数据库具有非常不一致的数据类型):

  foreach (var record in valuationQuery)
{
int CurrentValType = Convert.ToInt32(record.ValueTypeID);
string FieldName = "Value";

if (MPLower.MileagePointID >= 1 && MPLower.MileagePointID <= MaxMileagePoints)
{
FieldName = "Value" + MPLower.MileagePointID.ToString().Trim();
MPLower.MileagePointPounds[CurrentValType] = Convert.ToInt32(record.GetType().GetProperty(FieldName).GetValue(record, null));
}

if (MPHigher.MileagePointID >= 1 && MPHigher.MileagePointID <= MaxMileagePoints)
{
FieldName = "Value" + MPHigher.MileagePointID.ToString().Trim();
MPHigher.MileagePointPounds[CurrentValType] = Convert.ToInt32(record.GetType().GetProperty(FieldName).GetValue(record, null));
}
}

我是 C# 的新手(我继承了一些代码),所以我意识到这可能是我做过或没做过的蠢事!!请问有人能帮忙吗?

最佳答案

身份映射

使用 ORM 时的一个常见问题(好吧,也许不是很常见,但它可能会发生)是您希望返回不同记录的查询最终会返回同一记录的多个副本。这通常是由 ORM 的 Identity Map 引起的。以下是它通常如何工作的简要概述。

identity map本质上是一个对象缓存,基于每个对象的主键。

当您向 ORM 请求具有特定主键的记录时,它会检查该记录是否已存在于标识映射中。如果它已经存在,它将返回现有记录。

这通常很方便,但有时会出错。如果两个对象具有相同的主键,或者您没有指定主键是什么(强制 ORM 猜测),恒等映射无法区分它们,并且始终返回第一个。

这个故事的寓意是,如果您在不应该出现的地方看到同一条记录的多个副本,请始终仔细检查您的主键!


本题中的代码

    select new
{
v.Value1,
v.Value2,
v.Value3,
... snip ...
v.Value14,
v.Value15,
v.ValueTypeID
};

之所以有效,是因为您正在使用 select new{} 投影返回匿名类型,这会绕过身份映射。

    select v

直接选择对象,这确实使用了恒等映射,导致您看到的问题。

关于c# - foreach 循环在具有多条记录的 Linq 查询后仅返回第一条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16362405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com