0

数日前、2 つのクラスのマッピングとEF の使用に関する質問をしました。マッピングは順調に進んでいますが、オブジェクトに関連付けるクラスのナビゲーション プロパティでいくつかの問題に直面しています。1 人のユーザーのみのメッセージを読み込んでおり、そのユーザーのみに関連するステータスが必要です。ユーザーがメッセージを既読/未読としてマークしたかどうか、およびいつマークしたかを表示したいと思います。次のようなデフォルトの読み込みメカニズムを使用すると、ユーザーに関係なく、メッセージに関連するすべての履歴が読み込まれます。MessageMessageStatusHistoryStatusHistoryMessageMessageStatusHistory

IDbSet<Message> dbs = _repo.DbSet;
dbs.Include("StatusHistory").Where(x=>x.MessageIdentifier == msgIdentifier);

1人のユーザーのみの履歴をフィルタリングするには、次のトリックを試しました:

IDbSet<Message> dbs = _repo.DbSet;
var q = from m in dbs.Include("StatusHistory")
        where m.MessageIdentifier == msgIdentifier
        select new Message
        {
            MessageIdentifier = m.MessageIdentifier,
            /*OTHER PROPERTIES*/
            StatusHistory = m.StatusHistory
                             .Where(x => x.UserId == userId).ToList()
        };

return q.ToList();//THROWING ERROR ON THIS LINE

エラーが発生しています:

The entity or complex type 'MyLib.Biz.Message' cannot be constructed in a LINQ 
to Entities query.

私もコメントしてみましたStatusHistory = m.StatusHistory.Where(x => x.UserId == userId).ToList()が、助けにはなりませんでした。

フィルタリングされた StatusHistory でメッセージを取得するのを手伝ってください。

編集:-上記はこのコードで解決されます:

var q = from m in _repository.DBSet.Include("Histories")
        where m.MessageIdentifier == id
        select new {
                     m.Id,/*OTHER PROPERTIES*/
                     Histories = m.Histories.Where(x => 
                                   x.SenderId == userId).ToList()
                   };

var lst = q.ToList();
return lst.Select(m => new Message{
           Id = m.Id, MessageIdentifier = m.MessageIdentifier, 
           MessageText = m.MessageText, Replies = m.Replies, 
           ReplyTo = m.ReplyTo, Histories = m.Histories, SenderId = 
           m.SenderId, SenderName = m.SenderName, CreatedOn = m.CreatedOn
       }).ToList();

しかし、メッセージへの返信を含めようとすると:

from m in _repository.DBSet.Include("Replies").Include("Histories")

q.ToList()for を使用してクエリをリストに変換するとエラーが発生しますHistories = m.Histories.Where(x=> x.SenderId == userId).ToList()

4

1 に答える 1

0

ToList()EDIT 部分について:プロジェクションでIEnumerable<T>使用することはできませList<T>Message。また、2 つのリスト オブジェクトを作成する必要はありません。次を使用して、LINQ to Entities クエリから LINQ to Objects (2 つ目Select) に切り替えることができAsEnumerable()ます。

var list = (from m in _repository.DBSet
            where m.MessageIdentifier == id
            select new {
                // ...
                Histories = m.Histories.Where(x => x.SenderId == userId)
            })
            .AsEnumerable() // database query is executed here
            .Select(m => new Message {
                // ...
                Histories = m.Histories.ToList(),
                // ...
            }).ToList();

return list;

Includeで射影を使用する場合、 は効果がないことに注意してくださいselect。すでに で行ったように、プロジェクションの一部に含めたいプロパティを作成する必要がありますselect new { Histories....

于 2012-07-01T09:38:30.743 に答える