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);
}
}
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With