c#过滤器列表,删除任何双对象

本文关键字:任何双 对象 删除 过滤器 列表 | 更新日期: 2023-09-27 18:06:25

已经在这个论坛里搜索并测试了很多例子,但不能得到一个完整的工作方法。

我正在使用linq来批量插入一个实体类列表(remoterreads)。

由于唯一的约束,我需要过滤掉已经插入的任何项。

在remoter雷丁表中,唯一性由2列meterid和datetime组成。

// approx 5000 records (I need to do this in batches of 2000 due to a 
// constraint in L2S,but can do this after get this working)
List<RemoteReading> lst = createListFromCSV(); 
// Option 1:
// This does not work as am comparing memory list to db list. I need to use contains() method.
// Actually am trying to accomplish this infollowing examples.
List<RemoteReading> myLst = (from ri in db.RemoteReadings                                                       
                            from l in lst 
                            where l.meterid = ri.meterid 
                            && l.date = r.date
                            select ri).ToList();
////
// Option2:
// Get the list from DB that are in memory lst 
List<RemoteReading> myLst = (from ri in db.RemoteReadings                                                       
                            where 
                            // where in this list by comparing meaterid and datemeaured
                            (from l in lst
                            select 
/// help here !
///
                            select ri).ToList<RemoteInterconnectorReading>();

// Option3:
// Get the list from lst that are not in database
// I am bit confused here !

// Tried also to remove from list any duplicates:
List<RemoteReading> result = List<RemoteReading>)myLst.Except(lst).ToList<RemoteReading>();

// Ultimately
db.RemoteReading.InsertAllOnSubmit(result);
db.submitChanges();

请帮忙好吗?

c#过滤器列表,删除任何双对象

由于EF的限制,我们不能将DB查询与内存列表连接起来。此外,Contains只能与原语列表一起使用。因此,我们需要努力找出两列上的重复项。

var newItems = createListFromCSV();
var meterIds = newItems.Select(n=> n.meterid).Distinct().ToList();
var dates = newItems.Select(n=> n.date).Distinct().ToList();
var probableMatches = (from ri in db.RemoteReadings                              
                      where (meterIds.Contains(ri.meterids)
                      || dates.Contains(ri.date)
                      select new {ri.merterid, ri.date}).ToList();
var duplicates = (from existingRi in probaleMatches
                 join newRi in newItems
                 on new {existingRi.meterid, existingRi.date}
                 equals {newRi.meterid, newRi.date}
                 select newRi).ToList();
var insertList = newItems.Except(duplicates).ToList();
db.RemoteReadings.Insert(insertList); // or whatever

在aSharma的大力帮助和其他一些调整下,我终于得到了一个工作和测试的方法。由于我的列表包含超过5000个项目,我必须分批执行以覆盖2112个SQL RPC调用限制。添加了一些评论和信用:)

/// List<RemoteReadings> contains a list of database Entity Classes RemoteReadings 
        public List<RemoteReadings> removeDublicatesFirst(List<RemoteReadings> lst)
        {
            try
            {
                DataClasses1DataContext db = new DataClasses1DataContext();
                var meterIds = lst.Select(n => n.meterId).Distinct().ToList();
                var dates = lst.Select(n => n.mydate).Distinct().ToList();
                var myfLst = new List<RemoteReadings>();
                // To avoid the following SqlException, Linq query should be exceuted in batches as follows.
                //{System.Data.SqlClient.SqlException 
                // The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect.
                // Too many parameters were provided in this RPC request. The maximum is 2100.
                foreach (var batch in dates.Batch(2000))
                {
                    //  Gets a list of possible matches   from DB.
                    var probableMatches = (from ri in db.RemoteReadingss
                                           where (meterIds.Contains(ri.meterId)
                                           && batch.Contains(ri.mydate))
                                           select new { ri.meterId, ri.mydate }).ToList();
                    // Join the  probableMatches with the lst in memory on unique
                    // constraints meterid.date to find any duplicates
                    var duplicates = (from existingRi in probableMatches
                                      join newRi in lst
                                      on new
                                      {
                                          existingRi.meterId,
                                          existingRi.mydate
                                      }
                                      equals new { newRi.meterId, newRi.mydate }
                                      select newRi).ToList();
                    //Add duplicates in a new List due to batch executions.
                    foreach (var s in duplicates)
                    {
                        myfLst.Add(s);
                    }
                }
                // Remove the duplicates from lst found in myfLst;
                var insertList = lst.Except(myfLst).ToList();
                return insertList;
            }
            catch
        (Exception ex)
            {
                return null;
            }
        }

// Found this extension Class to divide IEnumerable in batches.
// http://stackoverflow.com/a/13731854/288865
 public static class MyExtensions
    {
        public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> items,
                                                           int maxItems)
        {
            return items.Select((item, inx) => new { item, inx })
                        .GroupBy(x => x.inx / maxItems)
                        .Select(g => g.Select(x => x.item));
        }
    }