1

This is a follow up to: Best way to save type of class in database?, well almost the same question but in a more general manner.

I often come across a situation where a base class/interface object has to be saved to database, and I need to read data back, instantiate as actual concrete objects and return a list.

A simple demo would explain it better.

interface IFeline
{
    Name;
}

class Leopard
{
    Name;
}

class Cheetah
{
    Name;
}

I would be saving to database like this:

IFeline felix = new Cheetah();
felix.Save(); //saved to db

Now I need to get a list of felines from db.

public IEnumerable<IFeline> GetThemAll()
{
     //connection
     //query command 
     //reader

     while(reader.Read())
         yield return new ... { } //how do I get the actual felines here?
}

I hope the question is clear. I do not have separate tables for every concrete class They are all generic, and one table is sufficient to hold them.

I want to get the concrete instance from table. I know some sort of type information has to be saved along with the data. I can try a few approaches like saving type as string in the db table, or even enum to denote the type in database. Now my question is, is there a common approach/industry standard to tackle this problem?

Community
  • 1
  • 1
nawfal
  • 70,104
  • 56
  • 326
  • 368
  • 1
    Dude, please don't try to reinvent the wheel. Use Entity Framework. Microsoft already invented that and they know better than you and me. – Federico Berasategui Feb 08 '14 at 07:59
  • @HighCore never worked with Entity Framework. Could you make it an answer with relevant reference to the portion that deals with this part? I would be happy to know how what procedure it does behind to determine the concrete type from a table record. – nawfal Feb 08 '14 at 10:52
  • A similar question: [polymorphism-with-database-query](http://stackoverflow.com/questions/970208/polymorphism-with-database-query) – nawfal Feb 09 '14 at 08:17

2 Answers2

1

I am not sure how you are saving to the database. Are you serializing and then saving it to database or just plain text?

If you are serializing then easiest way is to deserialize and you will get proper object.

If you are saving each property to its appropriate column in database then you need to have one extra column to identify type of object.

while(reader.Read())

if type of object is 'Cheetah' then
  Cheetah oFeline = new Cheetah { Name = "Cheetah_A" };
  FelineList.Add(oFeline);

if type of object is 'Leopard' then
  Leopard oFelineL = new Leopard { Name = "Leopard_A" };
  FelineList.Add(oFelineL);

So now you have one list that includes both objects 'Cheetah and Leopard'

List<IFeline> FelineList = new List<IFeline>();

foreach (IFeline obj in FelineList) {
    if ((obj) is Cheetah) {
        ListBox1.Items.Add(obj.Name);
    }
}

I hope that help!

nawfal
  • 70,104
  • 56
  • 326
  • 368
1

I don't know if this is a common approach or industry standard, but I think, as you mentioned, you could save the Type and assembly string along with the data. When getting them back, you could use Activator to return the proper type of object like this.

var assemblyName = reader["assembly_name"];
var typeName = reader["type_name"];

var instance = Activator.CreateInstance(assemblyName, typeName);
if (instance != null)
{
    var feline = instance.Unwrap();

    // reading object's properties

    yield return feline;
}
ssett
  • 432
  • 3
  • 6