2016-04-12 4 views
3

LINQ:マテリアライズド値がnullであるため、値タイプ「可能System.Int32」へのキャストが失敗した私のデータベースにLINQクエリを実行するときに、私は次のエラーを取得してい

キャスト値型に "マテリアライズされた の値がnullであるため、System.Int32 'が失敗しました。

これは、列の1つがnullを返すためだと思います。

SELECT DISTINCT c.CompanyID, b.ProductBrandID, s.AnimalName, a.AccreditationID, t.ProductTypeID 
FROM dbo.ProductBrand b 
INNER JOIN dbo.BrandManufacturer bm ON b.ProductBrandID = bm.ProductBrandID 
INNER JOIN dbo.Company c ON bm.ProductManufacturerID = c.CompanyID 
INNER JOIN dbo.AnimalSource s ON b.AnimalCode = s.AnimalCode 
LEFT OUTER JOIN dbo.BrandAccreditation ba ON b.ProductBrandID = ba.ProductBrandID 
LEFT OUTER JOIN dbo.Accreditation a ON ba.AccreditationID = a.AccreditationID 
LEFT OUTER JOIN dbo.BrandType bt ON b.ProductBrandID = bt.ProductBrandID 
LEFT OUTER JOIN dbo.ProductType t ON bt.ProductTypeID = t.ProductTypeID; 

ヌルがAccreditationID列にある次のT-SQLクエリを実装する私の試みです

var facts = (from b in Program.db.ProductBrands 
      join bm in Program.db.BrandManufacturers on b.ProductBrandID equals bm.ProductBrandID 
      join c in Program.db.Companies on bm.ProductManufacturerID equals c.CompanyID 
      join s in Program.db.AnimalSources on b.AnimalCode equals s.AnimalCode 
      join ba in Program.db.BrandAccreditations on b.ProductBrandID equals ba.ProductBrandID into bax 
      from credJoins in bax.DefaultIfEmpty() 
      join a in Program.db.Accreditations on credJoins.AccreditationID equals a.AccreditationID into ax 
      from accreds in ax.DefaultIfEmpty() 
      join bt in Program.db.BrandTypes on b.ProductBrandID equals bt.BrandTypeID into btx 
      from brandJoins in btx.DefaultIfEmpty() 
      join t in Program.db.ProductTypes on brandJoins.ProductTypeID equals t.ProductTypeID into tx 
      from types in tx.DefaultIfEmpty() 
      select new { c.CompanyID, types.ProductTypeID, b.ProductBrandID, accreds.AccreditationID, s.AnimalName }).Distinct(); 

:ここに私のLINQコマンドです。ここでの関係は以下のとおりです。

Entity Relationship Diagram

私の質問は2つの部分に実際にある:

  1. は私が正しくLINQに私のT-SQLクエリを翻訳していますか?
  2. 私は実際にnulls(したがって、左の外部結合)を予期しているとき、nullsに関連する問題をどのように解決するのですか?

ありがとうございます。

+2

あなたは 'Accreditations.AccreditationIDが定義されています'int?'として?代わりに、単に 'accreds.AccredidationId'の代わりに' AccreditationID = accreds?.AccreditationId'を選択する方法もあります。 – Rob

+0

@Robどうすればいいですか? –

+0

@Robあなたの構文はうまくいかなかった。いくつかの試行錯誤の後、私はこれを思いつきました:AccreditationID =(int?)accreds.AccreditationID –

答えて

3

(1)T-SQLクエリをLINQに正しく変換しましたか?

はい、正しく実行しました。

サイドノート(主な問題とは関係ありません):left outer joinを実行するときに別の名前を使用する必要はありません。 into句を使用すると、エンティティレコードにアクセスするために使用された名前が有効範囲外になり再利用できるため、結合タイプ(innerまたはleft outer)にかかわらず残りのクエリが類似して表示されます。例えば

join ba in Program.db.BrandAccreditations on b.ProductBrandID equals ba.ProductBrandID into bax 
from credJoins in bax.DefaultIfEmpty() 

あなたはintoと、次のfrom行を削除した場合、それはinner joinとその逆となります

join ba in Program.db.BrandAccreditations on b.ProductBrandID equals ba.ProductBrandID into baJoin 
from ba in baJoin.DefaultIfEmpty() 

である可能性があります。

(2)実際にヌル(つまり、左外部結合)が予想される場合、nullに関する問題をどのように解決するのですか?

これはleft join値型フィールドを持つ典型的なエラーです。実際には、完全なエラーメッセージは、ソリューションが含まれています

結果の型のジェネリックパラメータまたはクエリのいずれかがNULL可能タイプを使用する必要があります。言い換えれば

left outer joinright側から来て、ちょうど彼らのNULL可能同等に変換非NULL可能値型のフィールドを探します。あなたのケースでは

、ここに:

select new { c.CompanyID, types.ProductTypeID, b.ProductBrandID, accreds.AccreditationID, s.AnimalName } 

このようなフィールドはtypes.ProductTypeIDaccreds.AccreditationIDなので、修正が(彼らはタイプintであると仮定した場合)されます。

select new { c.CompanyID, (int?)types.ProductTypeID, b.ProductBrandID, (int?)accreds.AccreditationID, s.AnimalName } 
関連する問題