简体   繁体   English

使用LINQ to SQL定期删除一组记录的最佳方法

[英]Best way to periodically remove a set of records with LINQ to SQL

This is my first crack at a method that is run periodically during the lifetime of my ASP.NET application to clean up expired sessions stored in my database. 这是我在ASP.NET应用程序生命周期中定期运行的方法的第一次破解,以清理存储在我的数据库中的过期会话。 It seems to work pretty well, but the software engineer in me doesn't feel "right" about this code. 它似乎工作得很好,但我的软件工程师对这段代码感觉不对。 I've been working with LINQ to SQL for a few months now, but I'm not very confident in the following code. 我已经使用LINQ to SQL几个月了,但我对以下代码不太自信。 I'm worried about a few things: 我担心一些事情:

  1. Is the following code safe to run in a situation where the database is being accessed by different threads in my application? 以下代码是否可以在我的应用程序中的不同线程访问数据库的情况下运行? I have a decent understanding of the idea of transactions, but I want to make sure I'm using them properly. 我对交易的想法有一个很好的理解,但我想确保我正确使用它们。

  2. Is my query going to cause performance issues? 我的查询是否会导致性能问题? Or is it appropriate in this case to select all of the records in this particular table? 或者在这种情况下选择此特定表中的所有记录是否合适? This method only runs every 15 minutes, so it's not like that query will be made over and over again in a short period of time. 此方法仅每15分钟运行一次,因此不会在短时间内反复进行查询。

  3. Is there a better way that I could do this? 有没有更好的方法可以做到这一点? I have a nagging feeling that there is. 我有一种唠叨的感觉。

Code: 码:

/// <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;
}

This sounds like something you could easily do in a sproc. 这听起来像你可以在sproc中轻松做的事情。 SQLServer gives you a GETDATE() method that returns the current time... I don't see why you can't just SQLServer为您提供了一个返回当前时间的GETDATE()方法......我不明白为什么您不能这样做

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

Wouldn't that do the same thing? 那会不会做同样的事情?

One comment: you don't want TimeSpan.Minutes , you want TimeSpan.TotalMinutes . 一条评论:你不想要TimeSpan.Minutes ,你想要TimeSpan.TotalMinutes It may well be irrelevant most of the time, but it's a logical bug at least :) 大多数情况下它可能是无关紧要的,但它至少是一个逻辑错误:)

You can have a stored proc as a method on your database context. 您可以将存储过程作为数据库上下文的方法。 Why not write one that does what you want and then call it through your context? 为什么不写一个做你想做的事,然后通过你的上下文调用它? That way you can also make use of set logic rather than iterating over your collection. 这样你也可以使用设置逻辑而不是迭代你的集合。 (Linq to SQL might compile this away - not sure how it deals with deletes.) (Linq to SQL可能会编译它 - 不确定它如何处理删除。)

FWIW I published a piece of sample code a little while back showing an implementation of set-based/batch updates for Linq (single statement update instead of record-by-record). FWIW我发布了一段示例代码,后来显示了Linq的基于集合/批量更新的实现(单个语句更新而不是逐个记录)。

I haven't published the delete version of the same but will do soon (read: when I'm in the mood to type up another blog entry :) ). 我还没有发布相同的删除版本,但很快就会发布(阅读:当我有心情输入另一个博客条目:))。 Meanwhile you can derive it from the 'update' statement version. 同时,您可以从“更新”语句版本中派生出来。

You'll find a description and the source code here: 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/05/architecture-linq-to-sql-and-set-based-operations-更新语句/

Update: a 'delete' example can be found here: http://blog.huagati.com/res/index.php/2008/11/25/architecture-linq-to-sql-and-set-based-operations-delete-statements/ 更新:可以在此处找到“删除”示例: http//blog.huagati.com/res/index.php/2008/11/25/architecture-linq-to-sql-and-set-based-operations-删除语句/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM