我正在尝试找出一种处理 .NET 中重复事件的好方法,特别是针对 ASP.NET MVC 应用程序。这个想法是用户可以创建一个事件并指定该事件可以在特定间隔后重复发生(例如“每两周”、“每月一次”等等)。
解决这个问题的最佳方法是什么?我现在的头脑风暴是有两个表:Job 和 RecurringJob。作业是“主”记录,具有作业的描述以及其针对的客户的关键信息,而 RecurringJob 链接回作业并具有有关发生频率的附加信息(例如 1 表示“每月一次”)以及时间跨度(例如“每周”、“每月”)。问题是如何确定和设置下一次执行的作业,因为这必须是定期执行的操作。我对此有两种思路:该逻辑应该存储在数据库列中并定期更新,或者在代码中动态计算。
对于解决这个问题有什么想法或建议吗?
编辑:这是我正在创建的基于订阅的网络应用程序,目的是让服务企业轻松安排其常见的重复工作并跟踪其客户。因此,典型的用途可能是为史密斯先生创建每月发生的“修剪草坪”工作。确切的日期并不重要 - 客户能够看到史密斯先生每月修剪草坪并跟进他的情况关于它。
让我重新表述一下上面的内容,以更好地表达我的想法。该应用程序的示例用例可能如下所示:
- 用户提取 John Smith 的客户记录并单击添加作业链接。
- 用户填写表单以创建名称为“Cut lawn”、开始日期为 2009 年 11 月 15 日的作业,并选择一个复选框以指示该作业持续发生。用户会看到一个辅助屏幕,询问工作频率。用户指示(此时尚未决定如何 - 让我们假设选择列表)该作业每月发生一次。
- 用户单击“保存”。
现在,当用户查看 John Smith 的记录时,他们可以看到他有一个工作“Cut lawn”,该工作从 11/15/2009 开始每月发生一次。在主仪表板上,当距离假定的开始日期还有一周时,用户会看到显示的作业带有诸如“12/15/2009 - 修剪草坪(约翰·史密斯)”之类的指示符。预产期前一周,公司有人打电话给他预约,他说他要出城直到 2010 年 1 月 1 日,因此他希望将预约重新安排在该日期。我们的用户可以将作业的日期更改为 1/1/2010,现在重复将从该日期开始一个月(例如,下次将是 2/1/2010)。其背后的想法是,该应用程序针对的是草坪护理、水管工、地毯清洁工等企业,其中确切的日期并不那么重要(因为它可能并且会随着人们忙碌而改变),关键是给予向该公司发出一个信号,表明史密斯先生的每月服务即将到来,应该有人给他打电话,以确定确切的时间安排。实际上,为这些企业提供了一种跟踪重复业务并知道何时需要跟进客户的方法。
I am trying to figure out a good way to handle recurring events in .NET, specifically for an ASP.NET MVC application. The idea is that a user can create an event and specify that the event can occur repeatedly after a specific interval (e.g. "every two weeks", "once a month" and so on).
What would be the best way to tackle this? My brainstorming right now is to have two tables: Job and RecurringJob. Job is the "master" record and has the description of the job as well a key to what customer it's for, while RecurringJob links back to Job and has additional info on what the occurrence frequency is (e.g. 1 for "once a month") as well as the timespan (e.g. "Weekly", "Monthly"). The issue is how to determine and set the next occurrence of the job since this will have to be something that's done regularly. I've seen two trains of thought with this: This logic should either be stored in a database column and periodically updated, or calculated on the fly in the code.
Any thoughts or suggestions on tackling this?
Edit: this is for a subscription based web app I'm creating to let service businesses schedule their common recurring jobs easily and track their customers. So a typical use might be to create a "Cut lawn" job for Mr Smith that occurs every month The exact date isn't important - it's the ability for the customer to see that Mr Smith gets his lawn cut every month and followup with him about it.
Let me rephrase the above to better convey my idea. A sample use case for the application might be as follows:
- User pulls up the customer record for John Smith and clicks the Add Job link.
- The user fills out the form to create a job with a name of "Cut lawn", a start date of 11/15/2009, and selects a checkbox indicating that this job continually occurs. The user is presented with a secondary screen asking for the job frequency. The user indicates (haven't decided how at this point - let's assume select lists) that the job occurs once a month.
- User clicks save.
Now, when the user views the record for John Smith, they can see that he has a job, "Cut lawn", that occurs every month starting from 11/15/2009. On the main dashboard when it's one week prior to the assumed start date, the user sees the job displayed with an indicator such as "12/15/2009 - Cut lawn (John Smith)". A week before the due date someone from the company calls him up to schedule and he says he's going to be out of town until 1/1/2010, so he wants his appointment rescheduled for that date. Our user can change the date for the job to be 1/1/2010, and now the recurrence will start one month from that date (e.g. next time will be 2/1/2010). The idea behind this is that the app is targeting businesses like lawn care, plumbers, carpet cleaners and the like where the exact date isn't as important (because it can and will change as people are busy), the key thing is to give the business an indicator that Mr. Smith's monthly service is coming up, and someone should give him a call to determine when exactly it can be scheduled for. In effect give these businesses a way to track repeat business and know when it's time to followup with a customer.
发布评论
评论(4)
这是我之前考虑过的一个问题 - 尽管我还没有在现实世界中付诸实践,但您正在使用的元素如下:
到目前为止 发生的历史记录,就这么简单。这些是存储在数据库中的内容,是根据给定日期计算“下一个”日期的方法以及业务逻辑中存在的重复模式。
一般来说,对于您的客户来说,关键信息是下一个计划发生的事件的列表,因此只要正确维护这些事件(当您将当前事件标记为已完成时,您就会创建一个新的事件),该事件就会起作用。不幸的是,出于调度目的,您可能需要能够显示接下来的几次发生,这就是事情变得有趣的点(-:两个选择:动态计算(我认为这可能更好 - 特别是使用一些智能“缓存”) “)或预先计算哪个整体负载较少,但要管理的数据较多,并保持最新状态更复杂(完全不考虑创建计划条目的提前时间)。
所以 - 回答你的问题 - 我为什么要考虑基本上,因为唯一“固定”点是下一个预定的事件,您将希望根据其当前值(ish)从那里计算您的日记,如果如果它发生变化,那么您需要重新计算,您可以在保留为特定作业缓存的下一个日期列表方面发挥创意,以根据需要提高性能,但就真正的持久存储而言,您只对下一个日期感兴趣
。最后的几个想法 - 首先,如果发生的日期发生变化(如您的问题),下一个日期有两种选择,要么a)继续原来的时间表,无论更改(或什至取消) - 另一个挑战!)当前事件或 b)实际完成的时间表,即对于某些事情,我们希望它们在给定的一天每 n 周发生一次,但可能需要不时地来回调整日期,而对于我们想要的其他事情它们将在上次完成后 4 周发生。其次 - 正如 Jon 所提示的 - 您应该查看 iCal,不一定是为了实现,但肯定可以帮助理解构成日历条目和重复模式的元素。
This is one I've thought about a bit before - though I haven't put it into practice in the real world, the elements you're working with are as follows:
So far, so easy. Those are the things that get stored in the database, the means to caclulate a "next" date based on a given date and a recurrence pattern live in your business logic.
The key piece of information for your clients in general is the list of next scheduled occurences so as long as those are maintained correctly (you create a new one when you mark the current one as done) that will work. Unfortunately for scheduling purposes you probably need to be able to show the next several occurences and this is the point at which things get interesting (-: Two choices: Calculate on the fly (I think this is probably better - especially with some smart "cacheing") or precalculate which is less overall load but more data to manage and keeping it up to date is more complex (quite apart from considerations of how far ahead to create schedule entries).
So - to answer your question - why do I think on the fly is better? Well basically because the only "fixed" point is the next scheduled event, you're going to want to calculate your diary forward from there based on its current value (ish) and if it changes then you need to recalculate. You can get creative in terms of preserving a list of next dates cached for a particular job to aid performance as needed, but in terms of genuinely persistent storage you're only interested in the next date.
A couple of final thoughts - firstly if the date for an occurence is changed (as in your question) there are two options for the next date, either a) continue with the original schedule regardless of the change to (or even cancellation of - yet another challenge!) the current event or b) schedule from actual completion i.e. for some things we will want them to happen every n weeks on a given day but might need to wiggle the dates back and forth from time to time whereas for other things we want them to happen 4 weeks after the previous completion. Secondly - as prompted by Jon - you ought to look at iCal, not necessarily for implementations but certainly to help understand the elements of what might make up a calendar entry and a repeat pattern.
您的规则可能会变得多复杂?如果你能说服当权者让事情变得简单,你的生活将会更加愉快:)你还应该让他们签署各种测试情况 - 如果某件事计划在每月 30 日发生一次,应该是否发生在二月?至少通过使用日期(没有时间),您应该不用担心夏令时......
您可能想看看 DDay.iCal 或寻找其他 iCal (RFC 2445) 实现的 .NET - 但判断库的质量可能很棘手,因为它是一个复杂的领域,有大量的极端情况。
就数据库而言,我会即时计算它,除非这太痛苦了。显然,您必须在某处仍然拥有相同的“计算下一次出现”代码,并且它消除了定期更新的复杂性。
How complex are your rules likely to get? If you can persuade the Powers that Be to keep things simple, your life will be a lot more pleasant :) You should also get them to sign off on various test situations - if something is scheduled to occur once a month on the 30th, should it occur in February or not? At least by using dates (without times) you should get away without worrying about daylight saving time...
You might want to look at DDay.iCal or look for other iCal (RFC 2445) implementations for .NET - but judging the quality of the library could well be tricky, as it's a complex area with loads of corner cases.
In terms of the database, I would calculate it on the fly unless that proves too painful. You'd obviously have to still have the same "work out the next occurrence" code somewhere, and it removes the complexity of the periodic update.
将计划存储在数据库表或 xml 文件中是有意义的。主要是因为该作业只能由 ASP.NET 应用程序调度。该事件必须由另一个应用程序触发 - 最有可能是一个检查 ASP.NET 应用程序存储的配置的 Windows 服务。
至于表的结构,实际上取决于您到底需要安排什么 - 我想您真正需要的是用户 ID、作业 ID 和要在单个表中执行的日期。
storing the schedule in a database table or in an xml file makes sense. primarily because the job can only be scheduled by the asp.net application. The event will have to be triggered by another application - most likely a windows service that checks the configuration that is stored by the asp.net application.
as for the structure of the tables that really depends on what exactly you need to schedule - i imagine all you really need is user id, job id, and date to execute in a single table.
我已经在数据库方面单独看到了这种情况,让我告诉你,它变得真的丑陋。
我建议采用某种业务模型来处理重复事件的想法(即根据业务模型进行动态计算)。
就数据库而言,您肯定需要存储与业务模型相关的数据,但最重要的是,您应该考虑预测您的重复事件(可能长达一年左右) ,这将允许应用程序外部的用户能够使用您的事件。例如,如果您有一个报告系统需要知道人们的日程安排等。
I've seen this done soley on the database side, and let me tell you that it gets really ugly.
I would suggest having a business model of some sort that handles the idea of recurring events (i.e. calculating on the fly from the business model).
As far as the database goes, you'll definitely need to store the data involved with your business model, but on top of that you should consider forecasting your recurring events (perhaps up to a year or so), which will allow uses external to your application to be able to use your events. Example, if you have a reporting system that needs to know what people are scheduled for, etc.