【问题标题】:LINQ - delete rows from database table from an ArrayLINQ - 从数组中删除数据库表中的行
【发布时间】:2019-01-04 15:15:30
【问题描述】:

我有一个逗号分隔值(1、2、5、8),我将它们转换成这样的数组

string s =checkboxId.Value;
int[] nums = Array.ConvertAll(s.Split(','), int.Parse);

我想删除 id 在 nums 中的所有这些行。如何使用 LINQ 做到这一点?

试过这个:

  foreach(int id in nums)
    {
   DeleteById(id, uid);
   }
   public void DeleteById(int id, string userName)
    {            
        long uid = common.GetUserId(userName);

        IEnumerable<M> idList = dataContext.MD.Where(m => m.ID == id && m.UserId == uid);
        dataContext.MD.DeleteAllOnSubmit(idList);
        dataContext.dc.SubmitChanges();
    }

编辑: 我不想遍历每个数组项。有没有一种方法可以轻松传递数组并通过 LINQ 查询从数据库中删除所有记录?

【问题讨论】:

标签: c# linq


【解决方案1】:

将其解析为 IEnumerable。创建具有排除值的新列表,然后在方法 RemoveAll 中使用谓词将其删除。

一个例子:

        string s = checkboxId.Value;
        var nums = s.Split(new[]{','}, StringSplitOptions.RemoveEmptyEntries)
            .Select(int.Parse)
            .ToList();
        var toBeRemoved = new List<int>{1, 2, 5};
        var numberOfRemovedItems = nums.RemoveAll(toBeRemoved.Contains);

【讨论】:

  • 好点,我从来没有意识到你可以只传递一个函数而不是一个完整的 lambda
  • @BurnsBA 在您发表评论后,意识到我们可以对 'RemoveAll' 做同样的事情:D
【解决方案2】:

我相信这应该可行:

string s = checkboxId.Value;
int[] nums = Array.ConvertAll(s.Split(','), int.Parse);

 var uid = 1234;

 // I prefer LINQ syntax.  The lambda syntax is fine too.
 var idList = from m in dataContext.MD
              where m.UserId == uid && nums.Contains(m.id)
              select m;

dataContext.MD.DeleteAllOnSubmit(idList);
dataContext.SubmitChanges();

【讨论】:

  • 它说nums没有包含
  • 确保你有“使用 System.Linq;”
【解决方案3】:

你可以用 linq 做到这一点:

var arr = s.Split(',').Where(n => n != checkboxId.Value)
                      .Select(n => Convert.ToInt32(n))
                      .ToArray();

【讨论】:

  • 为什么需要Where 子句?条件n != to checkboxId.Value 将始终为真。
  • 实际上,当 checkboxId.Value 中没有逗号时(即只给出一个值),n 将等于 checkboxId.Value。但你可能不想过滤掉这些。
【解决方案4】:

选择时可以获取Uid:

var toDelete = checkboxId.Value
    .Split(new[]{','}, StringSplitOptions.RemoveEmptyEntries)
    .Select( x => {
        int parsedInt= 0;
        var isInt = int.TryParse(x , out parsedInt);
        return new {isInt, parsedInt}
    })
    .Where(x => x.isInt)
    .Select(x=> new {Id= x.parsedInt, Uid=common.GetUserId(x.parsedInt)});

foreach(var item in toDelete)
{
    dataContext.MD.DeleteAllOnSubmit(
        dataContext.MD
            .Where(m => m.ID == item.Id && m.UserId == item.Uid)
        )
}
dataContext.dc.SubmitChanges();

或者没有int.TryParse检查:

var toDelete = checkboxId.Value
        .Split(',')
        .Select(int.Parse)
        .Select(x=> new {Id= x.parsedInt, Uid=common.GetUserId(x.parsedInt)})

对我来说,最好的方法是在 dbml 中的对象之间建立适当的链接。所以你可以从一个对象到另一个对象,你不需要common.GetUserId() 或m.ID == item.Id &amp;&amp; m.UserId == item.Uid).First()。 完成后,您可以简单地:

var idToDelete = checkboxId.Value
        .Split(',')
        .Select(int.Parse);

var entitiesToDelete = dataContext.MD
                        .Where(x => toDelete.Contains(x.Id));


dataContext.MD.DeleteAllOnSubmit(entitiesToDelete);
dataContext.SubmitChanges();

【讨论】:

  • 有没有办法可以传递数组列表并删除所有id在数组中的记录?
  • @user1254053,您可以将enumerable&lt;object&gt; 传递给DeleteAllOnSubmit 并在上下文中删除。我想你正在使用 Linq2 sql 对吗?
  • dbml 和 linq 查询
  • 我已经用最佳的简单代码编辑了我的问题,但是.. 你的问题发展得有点快。它使大部分答案无效,因为您在发布时不够清楚并隐藏了部分问题。您应该将此问题编辑为原始发布和发布时的副本以及其他在数据库删除时清除的问题。说明您已经拥有不想删除的 ID 列表。并明确Id和用户ID之间的1-1或1-n关系
  • 非常感谢 xdtTransform 的建议。
【解决方案5】:

你有一个字符串1,2,5,8

将此字符串转换为int 的数组。你可以这样做。如果您的字符串仅包含int,请注意。

string s = "1,2,5,8";
var arrayInt = s.Split(',').Select(int.Parse);

接下来,您要删除 int ids 数组中的所有这些数字。

var arrayIntCleared = ids.ToList().Except(arrayInt);

【讨论】:

  • 无需将Split()返回的数组转换成List。此外, Select 采用接收单个对象的函数,并将其转换为不同的单个对象。您可以像以前一样使用 Lambda 创建这样的函数。或者您可以直接使用 .NET 提供的一个:var arrayInt = s.Split(',').Select(int.Parse);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2014-11-05
  • 2015-08-07
相关资源
最近更新 更多