3

単純に LINQ で動作しないコードに問題がありますが、単純な for..each として動作します。説明と解決策をいただければ幸いです。

次のように構成された3つのクラス User 、 User 、 UserPermissions があります。

クラスのユーザー

ObservableCollection<User> GetList

クラス ユーザー

Public int id  {get;set;}
Public string UserName  {get;set;}
Public UserPermissions Permissions {get;set;}

クラス UserPermissions

Public Int ID {get;set;}
Public int ApplicationID {get;set;}

これは機能し、正しいユーザーを返します。

Users users = new Users();
foreach (User u in users.GetList() )
{
    if (u.UserName==username && u.Permissions.ApplicationID == applicationId)
    {
        usr = u;
        break;
    }
}

以下のlinqは同じことを「すべき」ですが、そうではありません。出力ウィンドウにエラーが返されたり発生したりすることはなく、ステップオーバーした後、musers 変数は単に存在しません。キャストをより具体的にし、AsQueryable を使用しようとしました。2 つの from コマンドを使用して let p=u.Permissions を試してみましたが、何も修正されていないようです。

私の心配は、他のクラスがこれに悩まされ、後でより複雑なクエリが使用されるにつれて問題が発生することです。

var  musers = from Users.User u in UsersList
               where (u.UserName==userName) 
                       && (u.Permissions.ApplicationID == ApplicationId)
              select u.ID;

次のエラーに関するもう 1 つの情報はありますか?

var t1 = UsersList.SelectMany( u => u.Permissions);

エラー 1 メソッド 'System.Linq.Enumerable.SelectMany(System.Collections.Generic.IEnumerable, System.Func>)' の型引数は、使用法から推測できません。型引数を明示的に指定してみてください。

4

2 に答える 2

2
        var usr = users.GetList()
            .FirstOrDefault(
                p => p.UserName == username 
                    && p.Permissions.ApplicationID == applicationId);

実際にあなたのためにそれを行う必要があります。ユーザーが見つからない場合、FirstOrDefaultはnullを返すことができます...

于 2013-09-23T13:56:45.283 に答える
0

アダムは、アダムに感謝します。

デバッガーで、「var found=from...」が、found が作成され、linq ステートメントが実行された時点で値が含まれていることを示していることを確認しました。ただし、Adam が正しく述べているように、クエリを列挙する時点まで linq 列挙は延期されます。それがすべてうまくいった理由は、機能するコードのすぐ下に、THAT linq クエリの列挙をトリガーする for ループがあったためです。その上の他のものにはそのような列挙がなかったので、黙って失敗したかのように見えました!

列挙が発生する場所ではなく、コード内のポイントでlinqクエリをデバッグできるように、コンパイラが関数を最適化していたと思いますが、それは完全に間違っています! 笑。ToList()やCount()などの列挙関数を使わないと結果が出なくても、クエリ自体はある程度評価されているのではないかと思いました。

たとえば、以下のコードでは、f3 だけが何かを含んでいますが、他のコードは列挙されていないため、何も含まれていません!

var f1 = から .....;

var f2 = から ....;

var f3 = から ....;

他の多くのことを行い、関数を呼び出すこともできます

int カウント = f3.Count();

興味深いのは、行が実行された後でも f1、f2 は何もないことですが、f3 は列挙 (カウント) が行われる直後と直前に値を持っているため、コンパイラの最適化/デバッグがここで役割を果たしていると思います。

これが他の誰かに役立つことを願っています:)

于 2013-09-24T10:25:33.617 に答える