7

Linq から SQL への関連する質問が 2 つあります。私のモデルがどのように見えるかを確認するには、下の画像を参照してください。

質問1

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

アップデート 1.1:

次のように DataLoadOptions を使用しようとしました。

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

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

しかし、これは機能しません.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:

例外は一目瞭然です。オブジェクト グラフは Cyclic であってはなりません。また、行 2 が例外をスローしなかったと仮定すると、重複キーであるため、行 3 は例外をスローしたと確信しています。

更新 1.2 :

以下も機能しません (上記のUpdate 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."

私は今、これを解決する方法について本当に途方に暮れています。助けてください!

質問2

Entity.ChangedByUser私のDBの他のすべてのテーブル、したがってLinq to SQLモデルには、 (外部キー/関係にリンクされたEntity.ChangedByUserId)およびEntity.AddedByUserEntity.AddedByUserId外部キー/関係にリンクされた) 2つのフィールドがあります

Linq to SQL でこれらのフィールドを熱心にロードするにはどうすればよいですか? クエリで単純な結合を行う必要がありますか? または他の方法がありますか?

自己参照テーブルでの Linq to SQL の熱心な読み込み http://img245.imageshack.us/img245/5631/linqtosql.jpg

4

3 に答える 3

4

あらゆるタイプのサイクルは許可されていませんLoadWith<T>orはAssociateWith<T>コンテキストのすべての型に適用されるため、無限ループを防ぐ内部的な方法はありません。より正確には、SQL Server には SQL がなく、提供されたフレームワークで Linq が自動的に生成できる CTE を実際に超えているため、SQL の作成方法が混乱しているCONNECT BYだけです

利用可能な最良のオプションは、1 レベルの結合をユーザー テーブルに手動で実行して、子と匿名型の両方を返し、それらを返すことです。申し訳ありませんが、これはクリーンで簡単なソリューションではありませんが、これまでのところ Linq で利用できるのはこれだけです。

于 2009-09-09T01:19:11.597 に答える
3

たぶん、一歩下がって、関係でをしたいのか見てみることができますか?この情報を「8時間前にIainGallowayによって変更された」などでユーザーに表示したいとします。

次のようなものは動作しますか?:-

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
            };

(imo)を明確にするために、そこで匿名タイプを使用しました。必要に応じて、これらのプロパティをユーザータイプに追加できます。

2番目の質問については、通常のLoadWith(x => x.AddedByUser)などが問題なく機能するはずです。ただし、説明文字列をデータベースに直接保存することを好む傾向がありますが、説明の更新にはトレードオフがあります。 ChangedByUser.FullNameが変更され、ChangedByUserが削除された場合に複雑で直感に反することを行う必要がある場合(たとえば、ON DELETE CASCADE、またはコードでnullのChangedByUserを処理する場合)。

于 2009-09-08T13:06:23.023 に答える
0

Linq to Sql でこの問題の解決策があるかどうかはわかりません。Sql Server 2005 を使用している場合は、共通テーブル式を使用して必要な結果を取得し、DataContext.ExecuteQuery を使用してそれを実行する (再帰的な) ストアド プロシージャを定義できます。

于 2009-09-08T04:09:02.887 に答える