Paweł Hemperek
Paweł Hemperek

Reputation: 1180

Flexible properties mechanism

Let's say I have a class called Expense. I can add various types of car related expenses - tank expenses, repair expenses, tickets etc. Some properties of expense are the same for all types like cost, date etc., but there are some differences. For example: when I fuelled my car I want to save information like did I fully filled up my tank or not. However when I'm saving repair I want to save some other info.

The problem is - how to create some sort of flxible properties mechanism?

What I came up with is to have two tables: expenses and expenses_properties. In expenses table I could store all basic, common data and expenses_properties would have following structure:

| Id | PropertyName | PropertyValue | ExpenseId
|  1 | IsFull       | "true"        |     1
|  2 | Stuff        | "2016-10-02"  |     1

The problem is, for PropertyValue column I would have to use specific type, like nvarchar for example. In this case, I wouldn't be able to sort those values correctly (eg. by date)? Or maybe I would?

I think that there has to be a better way to do this using Entity Framework Code First approach.

Upvotes: 0

Views: 69

Answers (2)

ssis_ssiSucks
ssis_ssiSucks

Reputation: 1506

I would create your class/object model first (rather than the other way around, i.e., starting with the database):

public abstract class ExpenseBase 
{
    public DateTime ExpenseDate { get; set; }
    public double Cost { get; set; }
}

public class FuelExpense : ExpenseBase
{
    public  Boolean FilledUp { get; set; }
}

public class OtherExpense : ExpenseBase
{
    public string SomeOtherProperty { get; set; }
}

Then choose an inheritance mapping strategy. I usually go with "Table per Concrete class" (TPC) in this situation.

Upvotes: 1

peval27
peval27

Reputation: 1309

If there are different types of expenses, then it actually makes sense to have different classes (i.e. different tables). You can have Expenses where you can store common data and then TankExpense where you store specific "properties" with a column ExpenseId with can be a foreign key of Expense table Ids. When you need to retrieve an instance of expense you'll just retrieve if using EF and all the related expenses will appear:

if (myExpense.TankExpense.Length > 0)
{
    var isFull = myExpense.TankExpense[0].Full;
}

Upvotes: 0

Related Questions