0

我能够让我的方法(如下)在 LinqPad 中运行,但是当切换到我的实际代码(使用实体框架)时,我收到了这个错误:

“无法将类型 'System.Nullable`1' 转换为类型 'System.Object'。LINQ to Entities 仅支持转换 EDM 基元或枚举类型。”

如果我在此处取消注释两个注释行中的任何一个,则会发生错误(实际错误直到方法中的最后一行运行后才会发生):

public List<LotEquipmentScan> GetLotEquipmentScans(string maximoAssetNumber, decimal? manufacturerId, decimal? partNumber)
{
    var predicate = PredicateBuilder.True<LotEquipmentScanRecord>();

    // Note: Can't use == in where clause because of the possibility of nulls. That's why we're using object.Equals().
    if (maximoAssetNumber != "x") { predicate = predicate.And(scan => object.Equals(scan.MaximoAssetNumber, maximoAssetNumber)); }
    //if (manufacturerId != -1) { predicate = predicate.And(scan => object.Equals(scan.RawMaterialLabel.ManufacturerId, manufacturerId)); }
    //if (partNumber != -1) { predicate = predicate.And(scan => object.Equals(scan.RawMaterialLabel.PartNumber, partNumber)); }

    return Db.LotEquipmentScanRecords.AsExpandable().Where(predicate).ToList().Map();
}

我相信这是因为manufacturerId 和partNumber 是可以为的小数。问题是这些变量可以为空,我们甚至希望通过它们为空来过滤结果。这只是不适用于 EF,还是有一种优雅的方法来解决这个问题?

编辑

需要明确的是,当manufacturerId 作为null 传入时,使用此行会返回五行(我可以通过查看数据库来验证):

if (manufacturerId != -1) { predicate = predicate.And(scan => object.Equals(scan.RawMaterialLabel.ManufacturerId, manufacturerId)); }

使用这一行,不会返回任何行:

if (manufacturerId != -1) { predicate = predicate.And(scan => scan.RawMaterialLabel.ManufacturerId == manufacturerId); }

问题是当我传入一个好的制造商 ID 时,我得到了上面的错误。

4

1 回答 1

3

Bob Horn 的编辑/注释:这个答案被接受是因为下面的编辑,指定了 EF 中的一个错误。这个答案的第一部分没有用。

通过使用object.Equals(object, object)as 比较两个值类型的方法(Nullables 也是值类型),您隐式地将它们装箱。实体框架不支持这一点。

尝试改用==运算符:

// Since scan.RawMaterialLabel.ManufacturerId and manufacturerId are both Nullable<T> of the 
// same type the '==' operator should assert value equality, whether they have a value, or not.

// (int?)1 == (int?)1
// (int?)null == (int?)null
// (int?)1 != (int?)null

predicate = predicate.And(scan => scan.RawMaterialLabel.ManufacturerId == manufacturerId);

对于值类型,==运算符断言值相等,类似于 object.Equals() 对引用类型所做的。

编辑:

经过进一步调查,旧版本的 EF(EF5 之前)似乎存在一个错误

使用当前版本进行 Hacky 修复:

predicate = predicate.And(scan => 
   manufacturerId.HasValue
     ? scan.RawMaterialLabel.ManufacturerId == manufacturerId
     : scan.RawMaterialLabel.ManufacturerId == null);

但如果您的应用程序允许,请升级到 EF5。

于 2012-12-21T21:38:58.220 回答