我可以使用linq将表连接到列表吗?

时间:2013-12-10 14:13:17

标签: linq entity-framework c#-4.0

我有一张表格如下:

PersonalDetails

Columns are:

Name  
BankName
BranchName
AccountNo
Address

我有另一个包含'Name'和'AccountNo'的列表。 我必须从表中找到所有记录,其中“Name”和“AccountNo”分别出现在给定列表中。

任何建议都会有所帮助。

我已经完成了以下但没有多大用处:

var duplicationhecklist = dataAccessdup.MST_FarmerProfile
                          .Join(lstFarmerProfiles, 
                                t => new { t.Name,t.AccountNo}, 
                                t1 => new { t1.Name, t1.AccountNo}, 
                                (t, t1) => new { t, t1 })
                           .Select(x => new {
                                               x.t1.Name,
                                               x.t1.BankName,
                                               x.t1.BranchName,
                                               x.t1.AccountNo
                                             }).ToList();

其中lstFarmerProfiles是一个列表。

5 个答案:

答案 0 :(得分:19)

您可能发现无法使用本地实体对象列表加入Entity Framework LINQ查询,因为它无法转换为SQL。我会预先选择帐号上的数据库数据,然后加入内存。

var accountNumbers = lstFarmerProfiles.Select(x => x.AccountNo).ToArray();

var duplicationChecklist = 
        from profile in dataAccessdup.MST_FarmerProfile
                                     .Where(p => accountNumbers
                                                    .Contains(p.AccountNo))
                                     .AsEnumerable() // Continue in memory
        join param in lstFarmerProfiles on 
            new { profile.Name, profile.AccountNo} equals 
            new { param.Name, param.AccountNo}
        select profile

因此,您永远不会将批量数据拉入内存,但您可以继续进行最小的选择。

如果accountNumbers包含数千个项目,您可以考虑使用更好的可扩展chunky Contains method

答案 1 :(得分:3)

由于您要在.net中找到要查找的值的列表,请尝试使用Contains方法获取示例:

List<string> names = /* list of names */;
List<string> accounts = /* list of account */;

var result = db.PersonalDetails.Where(x => names.Contains(x.Name) && accounts.Contains(x.AccountNo))
                               .ToList();

答案 2 :(得分:2)

如果MST_FarmerProfile不是超大,我认为您最好选择使用AsEnumerable()将其带入内存并进行加入。

var duplicationhecklist = 
             (from x in dataAccessdup.MST_FarmerProfile
                        .Select(z => new {
                                            z.Name, 
                                            z.BankName, 
                                            z.BranchName,
                                            z.AccountNo
                                          }).AsEnumerable()
              join y in lstFarmerProfiles
                 on new { x.Name, x.AccountNo} equals new { y.Name, y.AccountNo}
              select x).ToList();

答案 3 :(得分:0)

如果accountNo识别记录,则可以使用:

var duplicationCheck = from farmerProfile in dataAccessdup.MST_FarmerProfile
                       join farmerFromList in lstFarmerProfiles
                       on farmerProfile.AccountNo equals farmerFromList.AccountNo
                       select new { 
                                      farmerProfile.Name, 
                                      farmerProfile.BankName, 
                                      farmerProfile.BranchName, 
                                      farmerProfile.AccountNo 
                                  };

如果您需要加入姓名和帐户,那么这应该有效:

 var duplicationCheck = from farmerProfile in dataAccessdup.MST_FarmerProfile
                        join farmerFromList in lstFarmerProfiles
                        on new
                        {
                            accountNo = farmerProfile.AccountNo,
                            name = farmerProfile.Name
                        }
                        equals new
                        {
                            accountNo = farmerFromList.AccountNo,
                            name = farmerFromList.Name
                        }
                        select new
                        {
                            farmerProfile.Name,
                            farmerProfile.BankName,
                            farmerProfile.BranchName,
                            farmerProfile.AccountNo
                        };

如果您只打算通过duplicateChecklist,那么离开.ToList()会更好地提升性能。

答案 4 :(得分:0)

由于数据通常位于不同的计算机上或至少位于不同的进程中:数据库 - 是一个而您的内存列表是您的应用程序,只有两种方法可以执行此操作。

  1. 尽可能将数据库部分从数据库下载到本地并在本地加入(通常使用AsEnumerable()或基本上ToList())。你在其他答案中对此有很多好的想法。
  2. 另一个是不同的 - 以某种方式将本地数据上传到服务器并在数据库端执行查询。上传可以不同的方式:使用一些临时表或使用VALUES。幸运的是,EF现在有一个小扩展(对于EF6和EF Core)你可以试试。它是EntityFrameworkCore.MemoryJoin(名称可能令人困惑,但它同时支持EF6和EF Core)。正如作者article中所述,它修改了传递给服务器的SQL查询,并使用本地列表中的数据注入 VALUES 构造。并且在DB服务器上执行查询。