Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read dynamic properties from database

I will try to explain my scenario the best way I can. I have the following tables in my database:

Products{ProductId, CategoryId ...}
Categories{CategoryId ...}
CategoryProperties{CategoryPropertyId, CategoryId, Name ...}
PropertyValues{ProductId, CategoryPropertyId, Value ...}

So the goal is to have list of products which belongs to some category and each category can have 'n' number of properties with values in the 'PropertyValues' table. I have a query that returns data based on 'categoryId' so I can always get different results from the database:

For the CPU category:

intel i7 | CPU | Model | Socket | L1 Cash | L2 Cahs | etc.

For the HDD category:

samsung F3 | HDD | Model | Speed | GB | etc.

So based on categories from my query as a result I always can get different column numbers and names. For database access I use simple ADO.NET call to stored procedure that return result. But because query result is dynamic in it's nature I don't know what is a good way to read this data.

I made a Product entity but I am confused how to make it really :( I thought that I can make a Product entity and make other entities which inherit Product like Cpu, Hdd, Camera, PcCase, GraphicCard, MobilePhone, Gps etc.

but I think that it's stupid because I can end this with 200+ entities in domain.

What would you do in this situation?
How to read and where to put this dynamic properties?

UPDATE - some solution

All right based on @millimoose suggestion for Dictionary and @Tim Schmelter idea to use DataTable object I came to some solution.
Now... this works I get data read them and I can display them.
But I still need advice from smarter people than me on am I did this good or should I handle this better or I am made some spageti code. So here what I did:

public class Product
    {
        public Product()
        {
            this.DynamicProperties = new List<Dictionary<string, string>>();
        }

        public List<Dictionary<string, string>> DynamicProperties { get; set; }

    }
...
List<Product> products = new List<Product>();
...
using (SqlDataAdapter a = new SqlDataAdapter(cmd))
                {
                    DataTable t = new DataTable();
                    a.Fill(t);

                    Product p = null;

                    foreach (DataRow row in t.Rows)
                    {
                        p = new Product();
                        foreach (DataColumn col in t.Columns)
                        {
                            string property = col.ColumnName.ToString();
                            string propertyValue = row[col.ColumnName].ToString();

                            Dictionary<string, string> dictionary = new Dictionary<string, string>();

                            dictionary.Add(property, propertyValue);

                            p.DynamicProperties.Add(dictionary);
                        }

                        products.Add(p);
                    }
                }
like image 825
1110 Avatar asked Mar 04 '13 21:03

1110


People also ask

What are the dynamic properties?

Dynamic properties of structures characterize a system in form of natural frequencies, damping and mode shape. These dynamic properties are used to formulate mathematical model for its behavior. The evaluation of dynamic properties of is Nnown as modal analysis.

What is dynamic property in C#?

Dynamic objects expose members such as properties and methods at run time, instead of at compile time. This enables you to create objects to work with structures that do not match a static type or format.


1 Answers

Your original approach

public class Product
{
    public List<Dictionary<string, string>> DynamicProperties { get; set; }
}

is quite good. I would use a custom collection though, with better naming so the intent is clearer.


You could also utilize C# 4.0's dynamic feature which more cool, but I'm not sure what benefit it gives in your case. You could do something like,

public class Product
{
    public List<dynamic> DynamicProperties { get; set; }
}

...

conn.Open();
using (var reader = cmd.ExecuteReader())
{
    var p = new Products();
    p.DynamicProperties = reader.AsDyamic().ToList();

    //or

    foreach (var item in reader.AsDynamic())
        yield return item;
}

// carry this extension method around
public static IEnumerable<dynamic> AsDynamic(this IDataReader reader)
{
    var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList();
    foreach (IDataRecord record in reader as IEnumerable)
    {
        var expando = new ExpandoObject() as IDictionary<string, object>;
        foreach (var name in names)
            expando[name] = record[name];

        yield return expando;
    }
}

Somewhat related question: How to convert a data reader to dynamic query results

like image 140
nawfal Avatar answered Sep 18 '22 16:09

nawfal