web-dev-qa-db-ja.com

Linqは、他のテーブルにない1つのテーブルからデータを選択します

こんにちは私は他のテーブルにない1つのテーブルからデータを選択するために次のコードを持っています

var result1 = (from e in db.Users
               select e).ToList();
var result2 = (from e in db.Fi
               select e).ToList();
List<string> listString = (from e in result1
                           where !(from m in result2
                                   select m.UserID).Contains(e.UserID)
                           select e.UserName).ToList();

ViewBag.ddlUserId = listString;

ListString内で値を取得していますが、listStringをビューバッグに追加中にエラーが発生しました。

Unable to cast object of type 'System.Collections.Generic.List`1[System.String]' to type 'System.Collections.Generic.IEnumerable`1[Main.Models.Admin.User]'.
9
Mizbella

まず、ViewBagで何が起こっているのかを確認できるように、メソッド全体で質問を更新できますか?コードは正常に機能するはずなので、ViewBagに値を割り当てても通常は問題ありません。

    ViewBag.property1 = 0;
    ViewBag.property1 = "zero";

正常に動作します。 ViewBagは動的です。後で実際に間違ったタイプの何かにViewBag.ddlUserIdを割り当てようとすると、そのエラーが発生する可能性があります。

声明も書き直していただきたいのですが、その理由を説明させていただきます。しばらくの間、db.UsersUserレコードがたくさん(> 100.000)あり、Fiについても同じであると仮定します。コードでは、result1result2は2つのリストになり、1つは> 100.000 Userオブジェクトを含み、もう1つは> 100.000 Fiオブジェクトを含みます。次に、これら2つのリストを相互に比較して、文字列のリストを作成します。ここで、Webサーバーがこれを処理するために必要なリソースを想像してみてください。データを取得するために別のSQLサーバーを実際に使用/アクセスすることを前提とすると、そのサーバーに作業を任せる、つまりUserIDのリストを作成する方がはるかに優れて高速になります。そのためには、KirillBestemyanovの回答または次のいずれかを使用します。

    var list = (from user in db.Users
                where !db.Fi.Any(f => f.UserID == user.UserID)
                select user.UserName).ToList()

これにより、SQLサーバーが実行するクエリが1つだけ生成されます。

    SELECT 
    [Extent1].[UserName] AS [UserName]
    FROM [dbo].[Users] AS [Extent1]
    WHERE  NOT EXISTS (SELECT 
        1 AS [C1]
    FROM [dbo].[Fi] AS [Extent2]
    WHERE [Extent2].[UserID] = [Extent1].[UserID]
    )}

最終的にあなたが望むものです...

詳細を明確にするために:

    var list = (from user in db.Users
                where !db.Fi.Any(f => f.UserID == user.UserID)
                select user.UserName).ToList()

次のラムダ式としても記述できます。

    var list = db.Users.Where(user => !db.Fi.Any(f => f.UserID == user.UserID))
               .Select(user => user.UserName).ToList()

これは、見た目からは、Kirill Bestemyanovの回答(見た目を似せるために少し変更したもの)とは少し異なります。

    var list = db.Users.Where(user => !db.Fi.Select(f => f.UserID)
                                            .Contains(user.UserID))
                              .Select(user => user.UserName).ToList();

ただし、実際には同じSQLステートメント、つまり同じリストが生成されます。

25
Major Byte

これを試してみてください。とても簡単です。

var result=(from e in db.Users
            select e.UserID).Except(from m in db.Fi
                                    select m.UserID).ToList();
4
Pranav

Linq拡張メソッドに書き直します。

List<string> listString = db.Users.Where(e=>!db.Fi.Select(m=>m.UserID)
                                                  .Contains(e.UserID))
                                  .Select(e=>e.UserName).ToList();

それを試してみてください、それはうまくいくはずです。

4
var res = db.tbl_Ware.where(a => a.tbl_Buy.Where(c => c.tbl_Ware.Title.Contains(mtrTxtWareTitle.Text)).Select(b => b.Ware_ID).Contains(a.ID));

T-SQLでのこの意味は次のとおりです。

SELECT * FROM tbl_Ware WHERE id IN (SELECT ware_ID, tbl_Buy WHErE tbl_Ware.title LIKE '% mtrTxtwareTitle.Text %')
0
sali