【问题标题】:Best way to periodically remove a set of records with LINQ to SQL使用 LINQ to SQL 定期删除一组记录的最佳方法
【发布时间】:2010-09-23 01:13:49
【问题描述】:

这是我第一次尝试在我的 ASP.NET 应用程序的生命周期内定期运行以清理存储在我的数据库中的过期会话的方法。它似乎工作得很好,但我的软件工程师对这段代码感觉不“正确”。我已经使用 LINQ to SQL 几个月了,但我对下面的代码不是很有信心。我担心几件事:

  1. 在我的应用程序中的不同线程访问数据库的情况下,以下代码是否可以安全运行?我对交易的概念有相当的了解,但我想确保我正确地使用它们。

  2. 我的查询会导致性能问题吗?或者在这种情况下选择这个特定表中的所有记录是否合适?此方法仅每 15 分钟运行一次,因此不会在短时间内重复查询。

  3. 有没有更好的方法可以做到这一点?我有一种挥之不去的感觉。

代码:

/// <summary>
/// Method, run periodically, to remove all sign in records that correspond to expired sessions.
/// </summary>
/// <param name="connectionString">Database connection string</param>
/// <returns>Number of expired sign in records removed</returns>
public static int Clean(String connectionString)
{
    MyDatabaseDataContext db = new MyDatabaseDataContext(connectionString);

    var signIns = db.SignIns.Select(x => x);
    int removeCount = 0;

    using (TransactionScope scope = new TransactionScope())
    {
        foreach (SignIn signIn in signIns)
        {
            DateTime currentTime = DateTime.Now;
            TimeSpan span = currentTime.Subtract(signIn.LastActivityTime);

            if (span.Minutes > 10)
            {
                db.SignIns.DeleteOnSubmit(signIn);
                ++removeCount;
            }
        }

        db.SubmitChanges();
        scope.Complete();
    }

    return removeCount;
}

【问题讨论】:

  • 我相信对 Select 的调用毫无意义。您应该只能使用“foreach (SignIn signIn in db.SignIns)”

标签: c# performance linq-to-sql tsql transactions


【解决方案1】:

这听起来像是您可以在存储过程中轻松完成的事情。 SQLServer 为您提供了一个返回当前时间的 GETDATE() 方法......我不明白为什么你不能只是

 DELETE * FROM tblSignIns 
 WHERE LastActivityTime < DATEADD("minute", -10, GETDATE());

这不是做同样的事情吗?

【讨论】:

  • 另外,Linq 的使用给系统带来了额外的开销,需要在 DB Server 和应用程序之间进行额外的通信
【解决方案2】:

一条评论:你不想要TimeSpan.Minutes,你想要TimeSpan.TotalMinutes大多数情况下可能无关紧要,但至少这是一个逻辑错误:)

【讨论】:

    【解决方案3】:

    您可以将存储过程作为数据库上下文中的方法。为什么不写一个做你想做的事,然后通过你的上下文调用它呢?这样,您还可以使用集合逻辑,而不是遍历您的集合。 (Linq to SQL 可能会将其编译掉 - 不确定它如何处理删除。)

    【讨论】:

      【解决方案4】:

      FWIW 我不久前发布了一段示例代码,展示了 Linq 的基于集合/批量更新的实现(单语句更新而不是逐记录更新)。

      我还没有发布相同的删除版本,但很快就会发布(阅读:当我有心情输入另一个博客条目时:))。同时你可以从'update'语句版本中得到它。

      您可以在此处找到说明和源代码: http://blog.huagati.com/res/index.php/2008/11/05/architecture-linq-to-sql-and-set-based-operations-update-statements/

      更新:可以在此处找到“删除”示例: http://blog.huagati.com/res/index.php/2008/11/25/architecture-linq-to-sql-and-set-based-operations-delete-statements/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-14
        • 1970-01-01
        相关资源
        最近更新 更多