泛型和数据库 - 一个设计问题
情况是我有一个对实体进行建模的表。该实体具有许多属性(每个属性由表中的一列标识)。问题是,将来我需要添加新属性或删除一些属性。问题是如何对数据库和相应的代码(使用 C#)进行建模,以便在出现这种情况时很容易“拥有”一个新属性。
一开始只有一个属性,所以我有一个专栏。我在类中定义了相应的属性,并具有适当的类型和名称,然后创建存储过程来读取它并更新它。然后是第二个属性,快速复制粘贴、更改名称和类型以及一些 SQL,就这样了。显然,这不是一个合适的模型。此时,你们中的一些人可能会建议使用 ORM(EF 或其他),因为这将自动生成 SQL 和代码,但目前这对我来说不是一个选择。
我想到只有一个程序用于读取一个属性(按属性名称),另一个程序用于更新它(按名称和值),然后是一些通用程序用于读取同一语句中实体的一堆或所有属性。如果您考虑使用泛型,这在 C# 中听起来可能很简单,但数据库不知道泛型,因此不可能有强类型解决方案。
我想要一个“尽可能强类型”的解决方案,这样我就不需要进行大量的转换和解析。我会在代码中定义可用属性,这样您就不会去猜测可用的属性并使用魔术字符串等。那么在系统中添加新属性的过程仅意味着向表中添加新列并在代码中(例如在枚举中)添加新属性“定义”。
The situation is that I have a table that models an entity. This entity has a number of properties (each identified by a column in the table). The thing is that in the future I'd need to add new properties or remove some properties. The problem is how to model both the database and the corresponding code (using C#) so that when such an occasion appears it would be very easy to just "have" a new property.
In the beginning there was only one property so I had one column. I defined the corresponding property in the class, with the appropriate type and name, then created stored procedures to read it and update it. Then came the second property, quickly copy-pasted, changed name and type and a bit of SQL and there it was. Obviously this is not a suitable model going forward. By this time some of you might suggest an ORM (EF or another) because this will generate the SQL and code automatically but for now this is not an option for me.
I thought of having only one procedure for reading one property (by property name) and another one to update it (by name and value) then some general procedures for reading a bunch or all properties for an entity in the same statement. This may sound easy in C# if you consider using generics but the database doesn't know generics so it's not possible to have a strong typed solution.
I would like to have a solution that's "as strongly-typed as possible" so I don't need to do a lot of casting and parsing. I would define the available properties in code so you don't go guessing what you have available and use magic strings and the like. Then the process of adding a new property in the system would only mean adding a new column to the table and adding a new property "definition" in code (e.g. in an enum).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
听起来你想这样做:
你有一个为此创建的表,但你不想在添加时继续更改该表
你需要像这样规范化表数据:
你的类看起来像这样:
当你创建你的表时从您的 DL 对象中,您可以枚举记录集。然后,您编写一次代码,检查与配置同名的属性(
BaseTableProperty.Name
==MyObj.
- 然后尝试将类型转换为 。然后,您只需将另一个属性添加到您的对象中,将另一个记录添加到
BaseTableProperty
中的数据库中,然后您就可以在中存储该人的值 。BaseTableValue
您有两个结果集,一个用于基本数据,另一个是从 Property 和 Value 表连接的。当您枚举每条记录时,您会看到
SomeProperty
的名称。 > -typeof(MyObj).GetProperty("SomeProperty")
存在吗?它是什么数据类型?好的,然后尝试将“100”转换为int
通过设置属性:对于每个属性。
It sounds like you want to do this:
You have a table created for that, but you dont want to keep altering that table when you add
You need to normalize the table data like so:
Your class would look like so:
When you create your object from your DL, you enumerate the record set. You then write code once that inspect the property as the same name as your configuration (
BaseTableProperty.Name
==MyObj.<PropertyName>
- and then attempt the type cast to that type as you enumerate the record set.Then, you simply add another property to your object, another record to the database in
BaseTableProperty
, and then you can store values for that guy inBaseTableValue
.Example:
You have two result sets, one for basic data, and one joined from the Property and Value tables. As you enumerate each record, you see a Name of
SomeProperty
- doestypeof(MyObj).GetProperty("SomeProperty")
exist? Yes? What it it's data type? int? Ok, then try to convert "100" toint
by setting the property:For each property.
即使你说你不能使用它们,这也是大多数 ORM 所做的。根据您使用的(或者甚至创建,如果这是一种学习体验),它们的复杂性和性能会有很大差异。如果您更喜欢轻量级 ORM,请查看 Dapper.Net。它也使用泛型,因此您可以检查代码,了解它是如何工作的,并根据需要创建您自己的解决方案。
Even if you said you cannot use them, that is what most ORM do. Depending on which one you use (or even create if it's a learning experience), they will greatly vary in complexity and performance. If you prefer a light weight ORM, check Dapper.Net. It makes use of generics as well, so you can check the code, see how it works, and create your own solution if needed.