- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我会尽我所能解释我的场景。我的数据库中有以下表格:
Products{ProductId, CategoryId ...}
Categories{CategoryId ...}
CategoryProperties{CategoryPropertyId, CategoryId, Name ...}
PropertyValues{ProductId, CategoryPropertyId, Value ...}
所以目标是拥有属于某个类别的产品列表,每个类别可以有 'n' 个属性,其值在 'PropertyValues' 表中。我有一个基于“categoryId”返回数据的查询,因此我总是可以从数据库中获得不同的结果:
对于 CPU 类别:
intel i7 | CPU | Model | Socket | L1 Cash | L2 Cahs | etc.
对于硬盘类别:
samsung F3 | HDD | Model | Speed | GB | etc.
因此,根据查询中的类别,我总是可以获得不同的列号和名称。对于数据库访问,我使用简单的 ADO.NET 调用来返回结果的存储过程。但是因为查询结果本质上是动态的,所以我不知道读取这些数据的好方法是什么。
我制作了一个 Product
实体,但我很困惑如何制作它:(我想我可以制作一个 Product
实体并制作其他 inherit Product
的实体,例如 Cpu
、硬盘
、相机
、电脑机箱
、显卡
、手机
、全局定位系统
等等。
但我认为这很愚蠢,因为我可以用域中的 200 多个实体 来结束这一切。
在这种情况下你会怎么做?
如何读取和放置此动态属性?
更新 - 一些解决方案
好吧,根据 @millimoose 对 Dictionary
的建议和 @Tim Schmelter 使用 DataTable
对象的想法,我找到了一些解决方案。
现在...这有效,我可以读取数据并显示它们。
但我仍然需要比我更聪明的人的建议,以了解我做得好吗,或者我应该更好地处理这件事,还是让我编写一些spageti 代码。所以这是我所做的:
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);
}
}
最佳答案
你原来的方法
public class Product
{
public List<Dictionary<string, string>> DynamicProperties { get; set; }
}
还不错。不过,我会使用自定义集合,命名更好,这样意图就更清楚了。
您还可以利用 C# 4.0 的 dynamic
功能,该功能更酷,但我不确定它对您的情况有何好处。你可以做类似的事情,
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;
}
}
有点相关的问题:How to convert a data reader to dynamic query results
关于c# - 如何从数据库中读取动态属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15211437/
你能比较一下属性吗 我想禁用文本框“txtName”。有两种方式 使用javascript,txtName.disabled = true 使用 ASP.NET, 哪种方法更好,为什么? 最佳答案 我
Count 属性 返回一个集合或 Dictionary 对象包含的项目数。只读。 object.Count object 可以是“应用于”列表中列出的任何集合或对
CompareMode 属性 设置并返回在 Dictionary 对象中比较字符串关键字的比较模式。 object.CompareMode[ = compare] 参数
Column 属性 只读属性,返回 TextStream 文件中当前字符位置的列号。 object.Column object 通常是 TextStream 对象的名称。
AvailableSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。 object.AvailableSpace object 应为 Drive 
Attributes 属性 设置或返回文件或文件夹的属性。可读写或只读(与属性有关)。 object.Attributes [= newattributes] 参数 object
AtEndOfStream 属性 如果文件指针位于 TextStream 文件末,则返回 True;否则如果不为只读则返回 False。 object.A
AtEndOfLine 属性 TextStream 文件中,如果文件指针指向行末标记,就返回 True;否则如果不是只读则返回 False。 object.AtEn
RootFolder 属性 返回一个 Folder 对象,表示指定驱动器的根文件夹。只读。 object.RootFolder object 应为 Dr
Path 属性 返回指定文件、文件夹或驱动器的路径。 object.Path object 应为 File、Folder 或 Drive 对象的名称。 说明 对于驱动器,路径不包含根目录。
ParentFolder 属性 返回指定文件或文件夹的父文件夹。只读。 object.ParentFolder object 应为 File 或 Folder 对象的名称。 说明 以下代码
Name 属性 设置或返回指定的文件或文件夹的名称。可读写。 object.Name [= newname] 参数 object 必选项。应为 File 或&
Line 属性 只读属性,返回 TextStream 文件中的当前行号。 object.Line object 通常是 TextStream 对象的名称。 说明 文件刚
Key 属性 在 Dictionary 对象中设置 key。 object.Key(key) = newkey 参数 object 必选项。通常是 Dictionary 
Item 属性 设置或返回 Dictionary 对象中指定的 key 对应的 item,或返回集合中基于指定的 key 的&
IsRootFolder 属性 如果指定的文件夹是根文件夹,返回 True;否则返回 False。 object.IsRootFolder object 应为&n
IsReady 属性 如果指定的驱动器就绪,返回 True;否则返回 False。 object.IsReady object 应为 Drive&nbs
FreeSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。只读。 object.FreeSpace object 应为 Drive 对象的名称。
FileSystem 属性 返回指定的驱动器使用的文件系统的类型。 object.FileSystem object 应为 Drive 对象的名称。 说明 可
Files 属性 返回由指定文件夹中所有 File 对象(包括隐藏文件和系统文件)组成的 Files 集合。 object.Files object&n
我是一名优秀的程序员,十分优秀!