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:
- Lookup table in the database I can query
- New property in my class (DaysValidFor) which has a custom getter that returns different values based on the DocumentType
- 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; }
}
}
Best Answer
If
DaysValidFor
is a property of the document type, then put it in theDocumentType
table, and look it up or join it with theDocuments
table.If
DaysValidFor
can be customized, add aDaysValidFor
field to the Documents table, and use theDaysValidFor
in theDocumentType
table as a default value when you are creating a newDocument
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 theDocumentID
, and look the value up from theDocuments
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.