C# 泛型和数据库——设计问题
现在的情况是,我有一个表来模拟一个实体。此实体具有多个属性(每个属性由表中的一列标识)。问题是,将来我需要添加新属性或删除一些属性。问题是如何对数据库和相应的代码进行建模(使用C#),以便在出现这种情况时,很容易“拥有”一个新属性 一开始只有一个属性,所以我有一个列。我用适当的类型和名称在类中定义了相应的属性,然后创建了存储过程来读取和更新它。然后是第二个属性,快速复制粘贴、更改名称和类型以及一些SQL,它就出现了。显然,这不是一个适合未来发展的模式。此时,你们中的一些人可能会建议使用ORM(EF或其他),因为这将自动生成SQL和代码,但目前这不是我的选择 我想只有一个过程来读取一个属性(按属性名称),另一个过程来更新它(按名称和值),然后是一些常规过程来读取同一语句中一个实体的一组或所有属性。如果你考虑使用泛型,但是数据库不知道泛型,所以不可能有强类型的解决方案。C# 泛型和数据库——设计问题,c#,sql-server,generics,strong-typing,C#,Sql Server,Generics,Strong Typing,现在的情况是,我有一个表来模拟一个实体。此实体具有多个属性(每个属性由表中的一列标识)。问题是,将来我需要添加新属性或删除一些属性。问题是如何对数据库和相应的代码进行建模(使用C#),以便在出现这种情况时,很容易“拥有”一个新属性 一开始只有一个属性,所以我有一个列。我用适当的类型和名称在类中定义了相应的属性,然后创建了存储过程来读取和更新它。然后是第二个属性,快速复制粘贴、更改名称和类型以及一些SQL,它就出现了。显然,这不是一个适合未来发展的模式。此时,你们中的一些人可能会建议使用ORM(E
我希望有一个“尽可能强类型化”的解决方案,这样我就不需要进行大量的转换和解析。我会在代码中定义可用的属性,这样您就不会猜测您有什么可用的属性,而是使用魔术字符串之类的东西。然后,在系统中添加新属性的过程只意味着在表中添加一个新列,并在代码中(例如在枚举中)添加一个新属性“定义”。即使您说您不能使用它们,这也是大多数ORM所做的。根据您使用哪一个(或者如果是学习体验,甚至创建),它们的复杂性和性能会有很大差异。如果您喜欢重量轻的ORM,请检查。它还使用泛型,因此您可以检查代码,了解其工作原理,并在需要时创建自己的解决方案。听起来您想这样做:
MyObj x = new MyObj();
x.SomeProperty = 10;
您已经为此创建了一个表,但您不希望在添加时继续更改该表
x.AnotherProperty = "Some String";
您需要像这样规范化表数据:
-> BaseTable
RecordId, Col1, Col2, Col3
-> BaseTableProperty
PropertyId, Name
-> BaseTableValue
ValueId, RecordId, PropertyId, Value
你的班级看起来是这样的:
public class MyObj
{
public int Id { get; set; }
public int SomeProperty { get; set; }
public string AnotherProperty { get; set; }
}
从DL创建对象时,枚举记录集。然后编写一次代码,以与配置相同的名称检查属性(BaseTableProperty.name
==MyObj.
-然后在枚举记录集时尝试将类型转换为该类型
然后,您只需向对象添加另一个属性,在BaseTableProperty
中向数据库添加另一条记录,然后就可以在BaseTableValue
中存储该对象的值
例如:
RecordId
========
1
PropertyId Name
========== ====
1 SomeProperty
ValueId RecordId PropertyId Value
======= ======== ========== =====
1 1 1 100
您有两个结果集,一个用于基本数据,另一个从属性和值表联接。当您枚举每个记录时,您会看到SomeProperty
-是否存在typeof(MyObj).GetProperty(“SomeProperty”)
存在?是吗?它的数据类型是什么?int?好的,然后尝试转换“100”通过设置属性来int
:
propertyInfo.SetValue(myNewObjInstance, Convert.ChangeType(dbValue, propertyInfo.PropertyType), null);
对于每个属性。为什么你不能使用EF?微软的天才们已经在这方面为你找到了答案并做了很多工作。我不想看到你重新发明轮子。是的,我不明白你为什么需要避免ORM。(另外,我不知道C#泛型与这些有什么关系)我同意,但EF在体系结构方面有点落后,所以我现在还不能使用它。“落后一点”是什么意思?为什么你不能使用它?我提到泛型是因为我仍然需要一些强类型的“感觉”。当你调用
GetProperty(“PropertyName”)时
总是返回Object
并没有多大帮助。我不想也不需要声明类中的每个属性。一次需要多个属性的情况很少发生。大多数情况下,我有对象ID,只需要知道其中一个属性。这就是为什么我要使用g通用的GetProperty(int-objectID,string-propertyName)
方法。我接受这个方法,因为它最接近我将要采用的解决方案。