C# NHibernate动态列数
在我的C项目中,我需要在代码中创建一个数据库,其中一个表具有动态列数。像这样C# NHibernate动态列数,c#,sql,nhibernate,dynamic,C#,Sql,Nhibernate,Dynamic,在我的C项目中,我需要在代码中创建一个数据库,其中一个表具有动态列数。像这样 ------------------------------------------------------------------------------ | Time ¦ Element #1 | Element#2 ¦ ... ¦ Element#N ¦ ------------------------------------------------
------------------------------------------------------------------------------
| Time ¦ Element #1 | Element#2 ¦ ... ¦ Element#N ¦
------------------------------------------------------------------------------
¦ TimeValue#1 ¦ Element#1Value#1 ¦ Element#2Value#1 ¦ ... ¦ Element#NValue#1 ¦
¦ TimeValue#2 ¦ Element#1Value#2 ¦ Element#2Value#2 ¦ ... ¦ Element#NValue#2 ¦
...
¦ TimeValue#M ¦ Element#1Value#M ¦ Element#2Value#M ¦ ... ¦ Element#NValue#M ¦
------------------------------------------------------------------------------
我使用简单的SQL查询“SQL创建表”
public void AddTable(string TableName, Dictionary<string,Type> columns)
{
...
string query = @"CREATE TABLE " + TableName + "(";
foreach (var c in columns)
{
SqlParameter temp = new SqlParameter();
string t = SetSQLType(ref temp, c.Value).ToString();
query += c.Key + " " + (t == SqlDbType.NVarChar.ToString() ? (t + "(200)") : (t)) + ",";
}
query = query.Substring(0, query.Length - 1);
query += " )";
...
}
但是我想,也许,我可以用更舒适的ORM来做这个,例如,NHibernate。我可以吗?我读过,但我不确定,在我的情况下我到底需要做什么
我想,我需要这样的东西:
public class Elements
{
public virtual DateTime Timestamp { get; set; }
public virtual IEnumerable<double> Values { get; set; }
}
ElemntId| TheKey | TheValue (e.g. nvarchar)
1 | "name" | "Element A"
1 | "time" | "20:02"
1 | "date" | "2013-05-22"
1 | "value" | "11.22"
我可以映射这个类吗?这个主题很有趣。也许乍一看不太清楚。把我的回答作为一个概述,一个来自下面列出的所有来源的总结。也许它会给你答案 从C的角度来看,您可以这样考虑这些动态属性
public virtual IDictionary<keyType, valueType> Additional { get; set; }
// (e.g. <string, object>
public virtual IDictionary Additional { get; set; }
我们现在充满活力。与合同相关的人员可能有0人、1人或1+人。他们中的每一个人都必须是独一无二的。我们还可以在运行时引入新的PersonTypes,并扩展任何合同的相关人员集
映射应该是这样的
<map name="Persons" table="ContractPerson" >
<key column="ContractId"/>
<index-many-to-many column="PersonTypeId" class="PersonType"/>
<one-to-many class="Person"/>
</map>
public class Elements
{
...
public virtual IDictionary<string, string> Values { get; set; }
}
C看起来像这样
<map name="Persons" table="ContractPerson" >
<key column="ContractId"/>
<index-many-to-many column="PersonTypeId" class="PersonType"/>
<one-to-many class="Person"/>
</map>
public class Elements
{
...
public virtual IDictionary<string, string> Values { get; set; }
}
这可能是映射:
<join table="ElemntValues" >
<key column="ElementId" />
<dynamic-component name="DynamicValues" >
<property name="Time" type="TimeSpan" />
<property name="Date" type="DateTime" />
<property name="Salary" type="decimal" />
<property name="Color" type="string" />
<property name="WorkingDays" type="integer" />
<many-to one....
...
</dynamic-component>
</join>
这些可能需要一些更特殊的处理插入、udpate和删除
Join将简化很多内容,但将始终用于SQL语句中,即使只需要父核心属性
它是动态的吗
我们得到了:
在C上,我们只有属性IDictionary ElementValues
NHibernate为我们做运行时检查。只能将正确类型的值插入到关键字“薪资必须为十进制”
有了一些元数据模型,我们就可以真正地对用户保持动态
任何映射属性都可以用于选择投影,用户会喜欢它
我们输了:
某些性能,因为将加载所有数据,例如session.Getid
在添加或删除列的情况下,我们不是动态的。所有映射都是应用程序分发的一部分,不能在运行时更改。我们总是可以重新部署新的映射。。。
2b词典和元数据
虽然从C的角度来看,IDictinary是非常动态的,但它可以
包含任何键/对值,由于NHibernate映射,内容为
管理。只能将整数值添加到映射为的属性中
整数但我们在运行时如何知道:我们有哪些密钥?什么
可以将值放在那里并从那里检索?同样,我们需要
一些元数据。。。不扮演钥匙的角色,但他们会
在运行时至关重要。NHibernate检查是最后一道防线
3如何更改运行时新增列中的映射?
那么,文件中说明了什么
这种映射的优点是能够确定
部署时组件的实际属性,只需编辑即可
映射文档。不支持映射文档的运行时操作
也可以使用DOM解析器
…使用DOM解析器。老实说,我不知道这意味着什么,如何实施
还有亚当·巴尔,请参见评论
我认为动态组件不可能在两个对象上都是动态的
和数据库级。请注意,零部件存储为
普通列,所以我们需要知道它的列表
但是有一个很好的想法,从看,太复杂的一些摘录。如果真的需要,这可能是一个真实动态世界的解决方案。。。运行时中的新列。。。IDictionary中的新键映射
总结
通过映射,我们可以非常动态。在运行时使用不同的键和值。不需要重新部署。但我们不能在select或order by中使用这些动态属性。很难根据这些值进行过滤
有了一个映射,我们就可以开箱即用了。但是我们确实有列中的数据,因此我们可以使用连接来检索它们。易于过滤、分类。而且/但必须有一些元数据来指导我们拥有什么以及我们能做什么
其他来源:
阿耶恩德
亚当·巴尔,
菲罗和
谢谢你的回答。非常有用。现在我可以动态生成列了,这真是太棒了。但我还有一个问题。在NHibernate中是否可以创建一个类和多个映射。例如,如果我需要类“元素”中的10个表,则可以在NHibernate中实现?表、列的数量。。。不是NHibernate的限制。但是“重复类/实体映射错误”怎么办?对于一个类只有一个表?好的,现在我明白了如何做到这一点,只需要创建多个配置,一个表一个配置。非常感谢你的帮助。
<join table="ElemntValues" >
<key column="ElementId" />
<dynamic-component name="DynamicValues" >
<property name="Time" type="TimeSpan" />
<property name="Date" type="DateTime" />
<property name="Salary" type="decimal" />
<property name="Color" type="string" />
<property name="WorkingDays" type="integer" />
<many-to one....
...
</dynamic-component>
</join>
<class entity-name="DynamicValues"...