2011-01-20 9 views
4

クエリにリテラル値を追加する必要があります。私の試み上記の例ではLinq Union:クエリにリテラル値を追加する方法は?

var aa = new List<long>(); 
aa.Add(0); 
var a = Products.Select(p => p.sku).Distinct().Union(aa); 

a.ToList().Dump(); // LinqPad's way of showing the values 

は、私はエラーを取得する:

"Local sequence cannot be used in LINQ to SQL implementation 
of query operators except the Contains() operator." 

私は例えばEntity Frameworkの4を使用していた場合は、は、私はいつも "が含まれるようにUNION文に何を追加することができますシード "ID?

私は、次のようなSQLコードを生成しようとしています:私は次の最も高い値が存在しないすべての値を見つけることができます後、私は自分自身にリストをjoinできるよう

select distinct ID 
from product 
union 
select 0 as ID 

(最低発見セット内の利用可能なID)。

編集:オリジナルのLINQクエリの利用可能な最低IDに

var skuQuery = Context.Products 
       .Where(p => p.sku > skuSeedStart && 
          p.sku < skuSeedEnd) 
       .Select(p => p.sku).Distinct(); 

var lowestSkuAvailableList = 
    (from p1 in skuQuery 
    from p2 in skuQuery.Where(a => a == p1 + 1).DefaultIfEmpty() 
    where p2 == 0 // zero is default for long where it would be null 
    select p1).ToList(); 
var Answer = (lowestSkuAvailableList.Count == 0 
       ? skuSeedStart : 
       lowestSkuAvailableList.Min()) + 1; 

を見つけるために、このコードは、1によりオフセット2 SKUがセットを作成し、次に高いが存在しないSKUを選択します。その後、最小のSKUが選択されます(最も低いSKUが次に使用可能な場合)。

これが機能するためには、シードはセットで一緒に結合されている必要があります。

答えて

4

あなたの問題は、必要なものがその上にローカル操作を含むLINQ-to-SQLクエリであるときに、クエリが完全にLINQ-SQLクエリに変換されていることです。

ソリューションは、あなたが(つまり、IEnumerable<T>見て拡張メソッド解像度を変更、ないIQueryable<T>)クエリを処理した後 LINQツーオブジェクトを使用したいコンパイラに伝えることです。これを行う最も簡単な方法はそうのように、クエリの最後にAsEnumerable()タックすることです:フロントアップ

var aa = new List<long>(); 
aa.Add(0); 
var a = Products.Select(p => p.sku).Distinct().AsEnumerable().Union(aa); 

a.ToList().Dump(); // LinqPad's way of showing the values 
+0

コード最終的には「シード」を下回らない可能な最小のIDを取得します。

次に、あなたはこのようなあなたの表現を書き換えることができます。現在、既存のIDから始まる最低のIDを取得します。したがって、なぜ "0"がクエリの一部である必要があるのか​​。 SQLでは、「製品ユニオンからID 0を選択してIDを選択」(私は別個の値を選択することを明確にするために追加しました) –

+0

@Dr。 Zim:このような実際のリテラル値をLINQ-to-SQLクエリに導入することは可能ではないと思います。あなたがより大きな文脈であなたの質問を投稿することができるならば、私たちは猫をスキンする別の方法を見つけることができるかもしれませんが、原則としてそれは不可能です。 –

+0

元のLinqクエリを追加しました:) –

1

:まさにあなたが尋ねた質問に答えるが、別の方法であなたの問題を解決しませ。

これはどう:

var a = Products.Select(p => p.sku).Distinct().ToList(); 

a.Add(0); 

a.Dump(); // LinqPad's way of showing the values 
+0

なぜ私はSKU全体をローカルに引き出すことができなかったのかをよりよく説明する元のLinqクエリを追加しました。 –

+0

ああ、そうだね... –

0

あなたが一定の値を格納するためのデータベーステーブルを作成し、UNION演算子をこのテーブルからクエリを渡す必要があります。

たとえば、1つのレコード( "SKU"、0)のみを持つフィールド "名前"と "値"を持つテーブル "デフォルト"を考えてみましょう。

 var zero = context.Defaults.Where(_=>_.Name == "SKU").Select(_=>_.Value); 
     var result = context.Products.Select(p => p.sku).Distinct().Union(zero).ToList(); 
関連する問題