2012-12-21 36 views
0

我能得到我的方法(下)在LinqPad運行,但切換到我的實際代碼時(使用實體框架),我得到這個錯誤:實體框架錯誤:異常與PredicateBuilder和比較空

"Unable to cast the type 'System.Nullable`1' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types."

如果我取消或者兩這裏註釋行發生

錯誤(直到方法的最後一行運行不發生實際的錯誤):

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和部分號碼爲可爲空小數。問題是那些變量可以爲空,我們甚至想通過它們爲空來過濾結果。這是否只適用於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); } 

問題是,當我傳入一個好manufacturerId,然後我得到上面的錯誤。

回答

3

編輯/鮑勃霍恩的筆記:這個答案被接受,因爲下面的編輯,指定EF中的錯誤。這個答案的第一部分沒有奏效。

通過使用object.Equals(object, object)作爲比較兩個值類型的方法(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)的bug

哈克修復與您的當前版本:

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

但是,如果你的應用程序允許的情況下,升級至EF5。

+0

那麼manufacturerId爲空,我想查找manufacturerId爲空的行呢? –

+0

如果'ManufacturerId'屬性同樣可以爲空,那麼應該可以使用'=='運算符。 –

+0

我認爲那樣做了。我需要使用manufacturerId.Value,而不僅僅是製造商ID。現在測試的準確性... –