这是我在ASP.NET应用程序生命周期中定期运行的方法的第一次破解,以清理存储在我的数据库中的过期会话。它似乎工作得很好,但我的软件工程师对这段代码感觉不对。我已经使用LINQ to SQL几个月了,但我对以下代码不太自信。我担心一些事情:
以下代码是否可以在我的应用程序中的不同线程访问数据库的情况下运行?我对交易的想法有一个很好的理解,但我想确保我正确使用它们。
我的查询是否会导致性能问题?或者在这种情况下选择此特定表中的所有记录是否合适?此方法每15分钟运行一次,因此不会在短时间内反复进行查询。
有没有更好的方法可以做到这一点?我有一种唠叨的感觉。
代码:
/// <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;
}
答案 0 :(得分:7)
这听起来像你可以轻松地做的事情。 SQLServer为您提供了一个返回当前时间的GETDATE()方法......我不明白为什么你不能只是
DELETE * FROM tblSignIns
WHERE LastActivityTime < DATEADD("minute", -10, GETDATE());
这不会做同样的事情吗?
答案 1 :(得分:2)
一条评论:您不希望TimeSpan.Minutes
,您想要TimeSpan.TotalMinutes
。它可能与大多数无关,但它至少是一个逻辑错误:)
答案 2 :(得分:1)
您可以将存储过程作为数据库上下文的方法。为什么不写一个做你想做的事,然后通过你的上下文调用它?这样你也可以使用设置逻辑而不是迭代你的集合。 (Linq to SQL可能会编译它 - 不确定它如何处理删除。)
答案 3 :(得分:1)
FWIW我在一段时间内发布了一段示例代码,显示了Linq的基于集合/批量更新的实现(单个语句更新而不是逐个记录)。
我还没有发布相同的删除版本,但很快就会发布(阅读:当我有兴趣输入另一个博客条目:))。同时,您可以从“更新”语句版本中获取它。
您可以在此处找到说明和源代码: 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/