2011-07-26 17 views
1

私は結果がLINQ to Sqlが空であり、オブジェクト参照がオブジェクトのインスタンスに設定されていません。エラー

var overlaps = from s in db.signups 
       join u in db.users on new { userid = s.userid } equals new  { userid = u.studentid } 
       join a in db.activities on new { activityid = s.activityid } equals new { activityid = a.id } 
       where 
        s.userid != Convert.ToInt32(Request.Cookies["studentid"].Value) && 
         (from signups in db.signups 
         where 
           signups.userid == Convert.ToInt32(Request.Cookies["studentid"].Value) 
          select new 
          { 
           signups.activityid 
          }).Contains(new { s.activityid }) 
         orderby 
          u.studentid 
         select new 
         { 
          a.name, 
          u.firstname, 
          u.lastname, 
          u.studentid, 
          u.email 
         }; 

は、私はLINQにかなり新しいので、私は実際にSQLを書いたんだ設定し、これをより効率的に行うことができますので、もし、LINQを生成するためにLinqerを使用取得するには、次のクエリを使用しますそれから私に知らせてください。それを言って、これは問題ではありません。

問題は、私は

foreach(var overlap in overlaps) 
{ 
    //do something 
} 

を行う際に、エラーが設定されていないオブジェクト参照を投げるということです。これはMVC 3アプリケーションで実行されています。

ただし、これをコンソールアプリケーションで実行すると問題なく実行されます。結果を返しません。私はDefaultIfEmptyを使用しようとしましたが、匿名型でこれを使用する方法に対処するものは何も見つかりません。

だから ...私のアプローチは正しいですか? そうでない場合は、どうすればよいですか?

ありがとうございます。

+0

問題は、あなたのLINQ文です。その内部のオブジェクトの1つが例外を引き起こしています。あなたがそのforeachを打つとLINQが実行されるだけです。 – scottheckel

+0

@Hexxagonal私の推測は、クエリ文字列パラメータです。 – asawyer

+0

クッキーが壊れています。おっとっと。 – asawyer

答えて

2

これがあなたの問題なのかどうかわかりませんが、あなたの結合構文は本当に奇妙です。

ここで匿名タイプを作成する必要はありません。直接比較するだけです。

select new 
{ 
    signups.activityid 
}).Contains(new { s.activityid }) 

だけで指定できます:

select signups.activityid).Contains(s.activityid) 

そして、なぜ世界であなたはint型にクッキーパラメータを変換するために、すべての作業をやり直したいです。このと同じ

join u in db.users on s.userid equals u.studentid 
join a in db.activities on s.activityid equals a.id 

何度も?

var studentId = Convert.ToInt32(Request.Cookies["studentid"].Value); 
//use this instead now in the query, dont repeat yourself 
+0

オリジナルのポストにあなたのコメントに基づいており、この回答に基づいて、私はどこか別の場所からこのコントローラからのコードを撮影したのだということを理解するようになりました。私は決してクッキーを設定していないことが判明しました。ここの大きな馬鹿。ご協力いただきありがとうございます。また、ローカル変数に値を代入する際の指針にも感謝します。私はいつも2つの方法の間に引き裂かれている。 – swasheck

0

ICBWが、私は重複をキャストしようとするだろう、のようなもの:もちろん

foreach(OverlapType overlap in overlaps as IEnumerable<OverlapType>) 
{ 
    //stuff 
} 

これはあなたがデータベースから取得されたオブジェクトのモデルを作成する必要がありますを意味します。しかし、実際に、あなたはとにかく1を持っている必要があり、それはMVCの背後にある全体の前提はある(モデルビューコントローラ)

0

さて、最初に私はあなたがダウンして最初の数行を簡素化することができますかなり確信して、オフに:

あなたはそれらの性質に外部キーを定義した場合
from s in db.signups 
join u in db.users on s.userid equals u.studentid 
join a in db.activities on s.activityid equals a.id 

実際には、あなたは、すべての参加する必要はありません - LINQは自動的にあなたのためにそれらを処理する:s.User.firstname代わりにu.firstnameなどについては

を書きます主な問題は、そのクエリのすべてのコンポーネント、主に "db"と"要求"(そしてコンソールアプリケーションでRequest.Cookiesがどのように正確に機能していますか?)

+0

haha​​haha!良いキャッチ、ありがとう。 Request.CookiesはIDで置き換えられます(0としましょう)。 'db'はデータコンテキストです。 DBにFKがある場合は、これらの結合は必要ありません。私はちょうどdb.signups中のSから ような何か '選択s.users.firstname'しますか? それは素晴らしいだろう – swasheck

1

あなたの最初の質問には、linqがいかに乱雑であるかを適切に心配しています...私たちはしばしば乱雑なlinqを取り、ちょうどdataContextを行います。 ExecuteQueryまたは。Linqの主な短所の1つは複雑なクエリを最適化する能力であるため、ExecuteCommandは可能です。

は、そこにどのようにひどくLINQしくじったクエリのアイデアを得るクエリアナライザを介して実行し、あなたは私の推測では、それがコミカルになるということです...で始まっ何にそれを比較します!

関連する問題