2011-11-26 3 views
5

私はLINQをかなり新しくしており、動作の不一致を回避できません。どんな知識のある入力でも大変感謝しています。私はSOや他の場所でも同様の問題を抱えていますが、彼らは役に立たないようです。LINQ - 以前に使用されていて検証済みのクエリ条件で '式を変換できませんでした'

私はとても簡単な設定 - 会社のテーブルと住所のテーブルを持っています。各企業は0以上のアドレスを持つことができ、> 0の場合はメインアドレスとして指定する必要があります。私は外部の結合を使用し、それに応じて選択ステートメントを変更する0のアドレスがある場合を処理しようとしています。

私は現在、出力をGridViewに直接バインドしていますので、クエリ内ですべての処理を続けたいと思います。

仕事

IQueryable query = 
    from comp in context.Companies 
    join addr in context.Addresses on comp.CompanyID equals addr.CompanyID into outer // outer join companies to addresses table to include companies with no address 
    from addr in outer.DefaultIfEmpty() 
    where (addr.IsMain == null ? true : addr.IsMain) == true // if a company has no address ensure it is not ruled out by the IsMain condition - default to true if null 
    select new { 
     comp.CompanyID, 
     comp.Name, 
     AddressID = (addr.AddressID == null ? -1 : addr.AddressID), // use -1 to represent a company that has no addresses 
     MainAddress = String.Format("{0}, {1}, {2} {3} ({4})", addr.Address1, addr.City, addr.Region, addr.PostalCode, addr.Country) 
    }; 

を行いますが、これはだから私は

MainAddress = (addr.AddressID == null ? "" : String.Format("{0}, {1}, {2} {3} ({4})", addr.Address1, addr.City, addr.Region, addr.PostalCode, addr.Country)) 

とするMainAddressフィールドを更新し、 ", ,()"

としてのGridViewで空のアドレスが表示されます今私はCould not translate expressionエラーとerewのspewey自動生成コードの束を得ていますrは私にはほとんど意味がありません。

私はMainAddressに追加条件があるAddressId上の労働条件に違いはありませんので、誰もがここで何が起こっているのか私に言うことができますか?

大変助かりました。

+2

が質問に "spewey自動生成されたコード" を追加することもできます。 – Bert

答えて

6

エラーは、LinqToSqlがヌルチェックを変換してからstring.Format式をSQLに変換できないことを示しています。あなたが最初のクエリが(LinqPadまたはSQLプロファイラのいずれかを使用して)生成されたSQLを見れば、あなたが何かわかりますあなたAddressIDフィールドで

SELECT [t0].[CompanyID], [t0].[Name], 
    (CASE 
     WHEN [t1].[AddressID] IS NULL THEN @p0 
     ELSE [t1].[AddressID] 
    END) AS [AddressID], 
    [t1].[Address1] AS [value], 
    [t1].[City] AS [value2], 
    [t1].[Region] AS [value3], 
    [t1].[PostalCode] AS [value4], 
    [t1].[Country] AS [value5] 
FROM [Company] AS [t0] 
LEFT OUTER JOIN [Address] AS [t1] ON [t0].[CompanyID] = [t1].[CompanyID] 
WHERE ([t1].[IsMain] IS NULL) OR ([t1].[IsMain] = 1) 

を、あなたはそれが処理するためにCASE-WHENを使用していることがわかりますAddressIDがnullの場合の条件。 MainAddressCASE-WHENを追加すると、そのフィールドで同じことをしようとしていますが、string.Formatに相当するSQLはないので、ELSE句に使用できるため、爆発します。

この問題を回避する簡単な方法は、メソッドを使用して文字列を書式設定することです。プライベートメソッドを呼び出すことにより、LinqToSqlは、SQLにstring.Formatを翻訳しようとはしません、代わりにAddressオブジェクトを移入するために必要なすべてのフィールドを返します。この方法は、その後の書式設定の世話をすることができます。例えば

LINQ:

.... 
select new { 
    comp.CompanyID, 
    comp.Name, 
    AddressID = (addr.AddressID == null ? -1 : addr.AddressID), 
    MainAddress = FormatAddress(addr) 
}; 

方法:

private static string FormatAddress(Address addr) 
{ 
    return (addr == null ? "" : 
      string.Format("{0}, {1}, {2} {3} ({4})", 
         addr.Address1, addr.City, 
         addr.Region, addr.PostalCode, addr.Country)); 
} 
+0

大きな助けと説明のために大変感謝します。私は、LINQのどの部分を試してデータベースに渡すのか分からなかった。私はいつもこの狂ったものについてもっと学んでいます... – tomfumb

+0

私は助けてくれると嬉しいです。 – rsbarro

関連する問題