2009-08-21 12 views
6

LinqからSQLに関連する2つの質問があります。私のモデルがどんなものか見てみるために、下の画像を見てください。自己参照表のSQLエンティティへのLinqの読み込みを熱心に

質問1

私は私のUserクラス/テーブルの上に熱心な負荷にどのようUser.AddedByUserフィールドを把握しようとしています。このフィールドは、User.AddedByUserIdフィールドの関係から生成されます。テーブルは自己参照型で、LinqにSQLへのアクセス方法を尋ねると、つまりUserエンティティがロード/フェッチされるたびに、User.AddedByUserとUser.ChangedByUserをフェッチする必要があるので、User.AddedByUserプロパティを熱心にロードします。 。しかし、私は、これは再帰的な問題になる可能性があることを理解...

アップデート1.1:

var options = new DataLoadOptions(); 
options.LoadWith<User>(u => u.ChangedByUser); 
options.LoadWith<User>(u => u.AddedByUser); 

db = new ModelDataContext(connectionString); 
db.LoadOptions = options; 

をしかし、これはない:私は次のようにDataLoadOptionsを使用しようとした

仕事、私は2行目に次の例外を取得:

System.InvalidOperationException occurred 
    Message="Cycles not allowed in LoadOptions LoadWith type graph." 
    Source="System.Data.Linq" 
    StackTrace: 
     at System.Data.Linq.DataLoadOptions.ValidateTypeGraphAcyclic() 
     at System.Data.Linq.DataLoadOptions.Preload(MemberInfo association) 
     at System.Data.Linq.DataLoadOptions.LoadWith[T](Expression`1 expression) 
     at i3t.KpCosting.Service.Library.Repositories.UserRepository..ctor(String connectionString) in C:\Development\KP Costing\Trunk\Code\i3t.KpCosting.Service.Library\Repositories\UserRepository.cs:line 15 
    InnerException: 

例外はかなり自己説明である - オブジェクトグラフが許可されていません周期的になる。 また、2行目が例外をスローしなかったと仮定して、3行目は重複したキーなので、私はかなり確信しています。

アップデート1.2

以下は(更新上記1.1と接続詞では使用しない)のいずれかで動作しない:

var query = from u in db.Users 
      select new User() 
      { 
       Id = u.Id, 
       // other fields removed for brevityy 
       AddedByUser = u.AddedByUser, 
       ChangedByUser = u.ChangedByUser, 

      }; 
return query.ToList(); 

なお、以下、自明例外をスローします。

System.NotSupportedException occurred 
Message="Explicit construction of entity type 'i3t.KpCosting.Shared.Model.User' in query is not allowed." 

私は現在これを解決する方法を失っています。助けてください! SQLモデルにしたがって

私のDB内の他のすべてのテーブルの上質問2

、およびLINQの、私はEntity.AddedByUserId外部キーにリンクされている(2つのフィールドEntity.ChangedByUserEntity.ChangedByUserId外部キー/関係にリンクされている)とEntity.AddedByUserを持っています/関係)

私はこれらのフィールドを賢く読み込むためにLinqにSQLをどうやって取得させるのですか?私のクエリで簡単な結合を行う必要がありますか?それとも別の方法がありますか?

Linq to SQL eager loading on self referencing table http://img245.imageshack.us/img245/5631/linqtosql.jpg

答えて

3

多分、あなたは何をしたいのかを見てみることができますどうすればいいですか?の関係で?私はあなたがこの情報をユーザーに表示したいと思っています。 "Iain Gallowayによる8時間前の変更"。

次のような作業はありますか? : -

var users = from u in db.Users 
      select new 
      { 
       /* other stuff... */ 
       AddedTimestamp = u.AddedTimestamp, 
       AddedDescription = u.AddedByUser.FullName, 
       ChangedTimestamp = u.ChangedTimestamp, 
       ChangedDescription = u.ChangedByUser.FullName 
      }; 

ここでは、わかりやすくするために匿名型を使用しています。必要に応じて、これらのプロパティをユーザータイプに追加することができます。

2番目の質問では、通常のLoadWith(x => x.AddedByUser)などはうまくいくはずですが、説明文字列をデータベースに直接格納する方が好きです - トレードオフがありますChangedByUser.FullNameが変更されたときに更新され、ChangedByUserが削除された場合(たとえば、ON DELETE CASCADEまたはnull ChangedByUserをコード内で処理する場合)、複雑で、直観に反することがあります。

+0

はい私はGUIにその情報を表示したいと思います。私は匿名型を使用せずにこの問題を解決することを望んでいました。しかし、私はそれが問題を解決する一つの方法だと思います。私の問題はLinq to SQLが多対多の関係に対処できないことに関連していますか? –

+0

Na、User.AddedDescriptionフィールドとUser.ChangedDescriptionフィールドをUserクラスに追加すると、anonタイプを使用する必要がなくなります。 多かれ少なかれ多くの関係(あなたの例の各関係は1:1)とは関係ありません。 SQLを直接作成していた場合は、AddedByUser(AddedByUserなどを含む)のすべてのプロパティを無限に取得することは望ましくありません。あなたはおそらく彼の名前をつかむだけで、あなたの意見に必要な細部をつかんでいます。 これはもっと一般的なO/RMの問題です。私は、L2EまたはHibernateで同じ問題があると思います。 –

0

はわからないLINQ to SQLはこの問題に対する解決策があります。 Sql Server 2005を使用している場合、一般的なテーブル式を使用して結果を取得し、DataContext.ExecuteQueryを使用してその結果を実行するストアドプロシージャを(再帰的な)ストアドプロシージャとして定義できます。

4

Any type of cycles just aren't allowedLoadWith<T>またはAssociateWith<T>はコンテキストのすべてのタイプに適用されるため、無限ループを防ぐための内部的な方法はありません。より正確に言えば、SQL ServerにはCONNECT BYCTEsがなく、Linqが提供されたフレームワークで自動的に生成できるものよりも実際にSQLを作成する方法が混乱しているだけです。

あなたが利用できる最適なオプションは、両方の子と匿名型のユーザーテーブルを手動で1レベル結合して戻すことです。申し訳ありませんがそれはクリーン/簡単な解決策ではありませんが、それはLinqとこれまでのところすべて利用可能です。

関連する問題