我有一个包含xml列的SQL Server数据库。我需要将该xml列映射到我的域实体中的expando对象。我使用NHibernate。我如何扩展NHibernate以适应此?我假设(我是NHibernate的新手),我必须覆盖实现来获取和设置XML数据,但我不知道如何在NHibernate中做到这一点。数据库中的NHibernate XML文档Expando实体中的对象
2
A
回答
2
感谢Petr的回答,我想出了以下用户类型的初始尝试来处理expando。它工作得非常好,现在我可以为每个对象提供客户端属性。我设置了每个对象必须拥有的属性,然后每个客户端都可以添加自己的属性来满足他们的需求。
一个警告 - 我只是为了持久性目的而设置它。在这个应用程序中搜索不是必需的,因为所有查询都是针对具有非规格化数据副本的MongoDB数据库完成的。
public class ExpandoUserType : IUserType
{
public object Assemble(object cached, object owner)
{
return cached;
}
public object DeepCopy(object value)
{
return value;
}
public object Disassemble(object value)
{
return value;
}
public bool Equals(object x, object y)
{
return false;
}
public int GetHashCode(object x)
{
return 0;
}
public bool IsMutable
{
get { return false; }
}
public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
{
var obj = NHibernateUtil.XmlDoc.NullSafeGet(rs, names[0]);
if (obj == null) return null;
var xmldoc = (XmlDocument)obj;
dynamic expando = new ExpandoObject();
foreach (XmlElement el in xmldoc.FirstChild.ChildNodes)
{
object val = null;
switch (Convert.ToString(el.Attributes["type"].InnerText).ToLower())
{
case "string":
val = el.InnerText;
break;
case "int32":
val = Convert.ToInt32(el.InnerText);
break;
case "int16":
val = Convert.ToInt16(el.InnerText);
break;
case "int64":
val = Convert.ToInt64(el.InnerText);
break;
case "bool":
val = Convert.ToBoolean(el.InnerText);
break;
case "datetime":
val = Convert.ToDateTime(el.InnerText);
break;
case "byte":
val = Convert.ToByte(el.InnerText);
break;
case "decimal":
val = Convert.ToDecimal(el.InnerText);
break;
}
((IDictionary<String, Object>)expando).Add(el.Name, val);
}
return expando;
}
/// <summary>
/// Transforms the expando object to an XML Document for storage in SQL.
/// </summary>
/// <param name="cmd"></param>
/// <param name="value"></param>
/// <param name="index"></param>
public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index)
{
if (value == null || value == DBNull.Value)
{
NHibernateUtil.String.NullSafeSet(cmd, null, index);
}
else
{
NHibernateUtil.XmlDoc.Set(cmd, expandoToXML((ExpandoObject) value, "root"), index);
}
}
public object Replace(object original, object target, object owner)
{
return original;
}
public Type ReturnedType
{
get { return typeof(ExpandoObject); }
}
public NHibernate.SqlTypes.SqlType[] SqlTypes
{
get { return new[] { NHibernateUtil.XmlDoc.SqlType }; }
}
private static XmlDocument expandoToXML(dynamic node, String nodeName)
{
XElement xmlNode = new XElement(nodeName);
foreach (var property in (IDictionary<String, Object>)node)
{
if (property.Value.GetType() == typeof(ExpandoObject))
xmlNode.Add(expandoToXML(property.Value, property.Key));
else
if (property.Value.GetType() == typeof(List<dynamic>))
foreach (var element in (List<dynamic>)property.Value)
xmlNode.Add(expandoToXML(element, property.Key));
else
{
XElement xnode = new XElement(property.Key, property.Value);
xnode.SetAttributeValue("type", property.Value.GetType().Name);
xmlNode.Add(xnode);
}
}
return xmlNode.GetXmlNode();
}
}
3
您必须为您的实体创建自定义类型(IUserType)。 Here有一篇不错的文章,介绍如何将XML列从数据库转换为NHibernate域实体。
相关问题
- 1. 对象库中的核心数据实体对象
- 2. JAXB和JPA - 引用数据库中同一对象的两个XML文档
- 3. 如何在数据库中保存没有实体的对象
- 4. 数据库中的对象和实体有什么区别?
- 5. 如何将XML文档映射到实体框架对象?
- 6. 从Sharepoint文档库中的InfoPath XML文件中提取数据
- 7. 巢XML在XML文档类型实体
- 8. 无法将实体对象保存到数据库中
- 9. 从列表数据库中删除对象实体
- 10. 数据库中的簇文本文档
- 11. XML到LINQ反序列化为XML文档中的对象
- 12. 在实体框架中添加json对象作为数据库中的BLOB
- 13. 将数据库和XML映射到对象的最佳实践
- 14. 替换数据库中的值和XML文档
- 15. 如何保存XML文档中的Oracle数据库
- 16. 发送XML文档中的HTTP主体
- 17. 向AccountController中的数据库添加新对象时IEntityChangeTracker的多个实例无法引用实体对象
- 18. 使用NHibernate的MySql数据库中的域对象中的DateTime分辨率
- 19. 数据库中的实体类
- 20. 更改实体中的数据库
- 21. 在视图中使用expando对象?
- 22. Xml文档使用DocumentBuilderFactory的DOM对象
- 23. 从Universe数据库生成XML文档
- 24. 作为nHibernate实体的参数返回对象
- 25. 如何声明XML文档中的“nbsp”实体
- 26. 通过PHP清理XML文档中的十六进制实体
- 27. SQL数据库,实体数据模型和1对1实体
- 28. 对Expando对象的ObservableCollection进行排序
- 29. 如何用NHibernate从数据库中获取对象?
- 30. 如何从Oracle数据库中的对象类型生成XML