0

I am writing an MVC4 application to track documents we have on file for our clients. I'm using code first, and have created models for my objects (Company, Document, etc...). I am now faced with the topic of document expiration.

Business logic dictates certain documents will expire a set number of days past the document date. For example, Document A might expire in 180 days, Document 2 in 365 days, etc... I have a class for my documents as shown below (simplified for this example).

What is the best way for me to create a lookup for expiration values? I want to specify documents of type DocumentA expire in 30 days, type DocumentB expire in 75 days, etc... I can think of a few ways to do this:

  1. Lookup table in the database I can query
  2. New property in my class (DaysValidFor) which has a custom getter that returns different values based on the DocumentType
  3. A method that takes in the document type and returns the number of days

and I'm sure there are other ways I'm not even thinking of. My main concern is a) not violating any best practices and b) maintainability. Are there any pros/cons I need to be aware of for the above options, or is this a case of "just pick one and run with it"?

One last thought, right now the number of days is a value that does not need to be stored anywhere on a per-document basis -- however, it is possible that business logic will change this (i.e., DocumentA's are 30 days expiration by default, but this DocumentA associated with Company XYZ will be 60 days because we like them). In that case, is a property in the Document class the best way to go, seeing as I need to add that field to the DB?

namespace Models
{
    // Types of documents to track
    public enum DocumentType
    {
        DocumentA,
        DocumentB,
        DocumentC // etc...
    }

    // Document model
    public class Document
    {
        public int DocumentID { get; set; }

        // Foreign key to companies
        public int CompanyID { get; set; }

        public DocumentType DocumentType { get; set; }

        // Helper to translate enum's value to an integer for DB storage
        [Column("DocumentType")]
        public int DocumentTypeInt
        {
            get { return (int)this.DocumentType; }
            set { this.DocumentType = (DocumentType)value; }
        }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}", ApplyFormatInEditMode = true)]
        public DateTime DocumentDate { get; set; }


        // Navigation properties
        public virtual Company Company { get; set; }
    }
}
2

If DaysValidFor is a property of the document type, then put it in the DocumentType table, and look it up or join it with the Documents table.

If DaysValidFor can be customized, add a DaysValidFor field to the Documents table, and use the DaysValidFor in the DocumentType table as a default value when you are creating a new Document record.

Rationale

By having a DocumentType table from the start, you provide a container by which all sorts of other features become possible as a function of that document type. You also avoid a redesign when you find out you need a DocumentType table, and you didn't provide one. Not every domain object needs such a type table, but documents are naturally organized into categories, so it's a good fit here.

You can have a DaysValidFor method in your repository if you want one. Pass it the DocumentID, and look the value up from the Documents table.

If you think in terms of classes instead of tables (i.e. "code first"), just substitute the word "class" for the word "table" in the two paragraphs above.

  • Thanks for the answer -- DocumentType does not have a separate class/table currently...it is currently an enum. I have no problem changing that to a lookup table (my option #1 listed in the question), just trying to see what the best design option would be... – Jim Oct 1 '13 at 17:37
  • Having it as a lookup table from the start is going to avoid some problems down the road. You're going to find out that you will need some other attributes attached to a document type, so you're going to need a DocumentType table anyway. But go ahead and put the DaysValidFor field in the Document table also. Having it there means you don't have to join the DocumentType table if you just want DaysValidFor. – Robert Harvey Oct 1 '13 at 17:39
  • OK, so I would have a DaysValidFor field in the Documents table to store the per-document value, and then a lookup table DocumentTypes that has a list of doc types and default values I can use for the days valid value, right? – Jim Oct 1 '13 at 17:43
  • Yes, that's right. – Robert Harvey Oct 1 '13 at 17:45
  • @RobertHarvey I'm wondering if that does not break YAGNI? I like to start with as simple as possible - hardcoded values, enums, etc. and if it really has rapidly changing values, bring in database table/editing/etc - because each additional table brings some complexity. – Giedrius Oct 3 '13 at 11:35
0

Hum, to each one his own way to see things, but to me this has nothing to do with C# MVC 4, and everything to do with the database itself, as this is linked to the data, not the way they are accessed.

I think I would create a View (SQL View, not MVC...) with a calculated column for the expiration date. This way you can use any criteria you want, check if documents are linked, the company, the type of document, just anything you need, and change those criterias as many time as needed, without any change in the MVC application.

I know you can create stored procedures with Code First, I am not too sure bout Views, but really from my point of view this belongs into the database, so that's what I would be looking to do.

  • 1
    @Giedrius Unless I totally misunderstand, YAGNI has nothing to say about database design, but with coding principles. I doubt mixing the 2 bring good results. – BernardG Nov 2 '13 at 17:04
  • Why on earth would you ever be calculating business logic in a data store? All he has to do is calculate an expiration date upon document creation and save that. The actual lookup value should either be drawn from a table or config file. – Mr Cochese Nov 2 '13 at 20:13
  • Again, from my point of view, this is NOT (business) logic, but data. Expiration date is an attribute of a document, just as its title, number of words and author. The fact that it is calculated (as a number of words is), does not change its nature. – BernardG Dec 1 '13 at 9:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.