博客
关于我
NHibernate动态添加表
阅读量:795 次
发布时间:2023-02-15

本文共 15509 字,大约阅读时间需要 51 分钟。

NHibernate动态添加表

设置和差不多,添加了一个模板hbm.xml文件,用于创建动态hbm.xml,HibernateUtil无改动。

 

MappingManger添加了两个方法

1      public static void UpdateClassMapping(DynamicTestModel dynamicModel) 2         { 3             var session = HibernateUtil.Instance.CurrentSession; 4             var fileName = "hbm_template/Template.hbm.xml"; 5             var file = File.ReadAllText(fileName); 6             file = file.Replace("@assembly", dynamicModel.GetType().Assembly.GetName().Name) 7                 .Replace("@namespace", dynamicModel.GetType().Namespace) 8                 .Replace("@class", dynamicModel.EntityName) 9                 .Replace("@table", "Dynamic_" + dynamicModel.EntityName);10 11             var xDocument = new XmlDocument();12             xDocument.LoadXml(file);13 14             var dynamicElements = xDocument.DocumentElement.GetElementsByTagName("dynamic-component");15             XmlElement dynamicElement = null;16             if (dynamicElements.Count > 0)17             {18                 dynamicElements[0].InnerXml = string.Empty;19                 dynamicElement = dynamicElements[0] as XmlElement;20             }21 22             foreach (DictionaryEntry property in dynamicModel.CustomProperties)23             {24                 var newElement = CreatePropertyElement(xDocument, dynamicElement.NamespaceURI, property);25                 dynamicElement.AppendChild(newElement);26             }27 28             Console.WriteLine(xDocument.OuterXml);29             xDocument.Save("hbm/" + dynamicModel.EntityName + ".hbm.xml");30         }31 32         private static XmlElement CreatePropertyElement(XmlDocument document, string parentNamespace, DictionaryEntry property)33         {34             var element = document.CreateElement("property", parentNamespace);35 36             element.SetAttribute("name", property.Key as string);37             element.SetAttribute("column", property.Key as string);38             element.SetAttribute("type", property.Value.GetType().Name);39             element.SetAttribute("not-null", "false");40             return element;41         }

 

CustomizableEntity类添加了一个属性

public string auto_id { get; set; }

 

创建类DynamicTestModel

1 namespace DynamicTableTest.DynamicTable 2 { 3     public class DynamicTestModel : CustomizableEntity 4     { 5         public string EntityName { get; set; } 6  7  8         public DynamicTestModel(string entityName) 9         {10             // TODO: Complete member initialization11             this.EntityName = entityName;12         }13     }14 }

 

添加DynamicEntityTuplizer

1 using NHibernate;  2 using NHibernate.Mapping;  3 using NHibernate.Properties;  4 using NHibernate.Proxy;  5 using NHibernate.Proxy.Map;  6 using NHibernate.Tuple;  7 using NHibernate.Tuple.Entity;  8 using System.Collections.Generic;  9  10 namespace DynamicTableTest.DynamicTable 11 { 12     public class DynamicEntityTuplizer : AbstractEntityTuplizer 13     { 14         private static readonly IInternalLogger log = LoggerProvider.LoggerFor(typeof(PocoEntityTuplizer)); 15  16         private static readonly DynamicModelAccesser Accessor = new DynamicModelAccesser(); 17         private sealed class DynamicModelMapInstantiator : IInstantiator 18         { 19             private readonly string entityName; 20             private readonly HashSet
isInstanceEntityNames = new HashSet
(); 21 22 private PersistentClass mappingInfo; 23 24 public DynamicModelMapInstantiator() 25 { 26 entityName = null; 27 } 28 29 public DynamicModelMapInstantiator(PersistentClass mappingInfo) 30 { 31 this.mappingInfo = mappingInfo; 32 entityName = mappingInfo.EntityName; 33 isInstanceEntityNames.Add(entityName); 34 if (mappingInfo.HasSubclasses) 35 { 36 foreach (PersistentClass subclassInfo in mappingInfo.SubclassClosureIterator) 37 isInstanceEntityNames.Add(subclassInfo.EntityName); 38 } 39 } 40 41 public object Instantiate(object id) 42 { 43 return Instantiate(); 44 } 45 46 public object Instantiate() 47 { 48 var model = new DynamicTestModel(entityName); 49 return model; 50 } 51 52 public bool IsInstance(object obj) 53 { 54 var that = obj as DynamicTestModel; 55 if (that != null) 56 { 57 if (entityName == null) 58 { 59 return true; 60 } 61 string type = that.EntityName; 62 return type == null || isInstanceEntityNames.Contains(type); 63 } 64 else 65 { 66 return false; 67 } 68 } 69 } 70 71 public DynamicEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) 72 : base(entityMetamodel, mappingInfo) 73 { 74 // NH different behavior fo NH-1587 75 Instantiator = BuildInstantiator(mappingInfo); 76 } 77 78 public override System.Type ConcreteProxyClass 79 { 80 get { return typeof(DynamicTestModel); } 81 } 82 83 public override bool IsInstrumented 84 { 85 get { return false; } 86 } 87 88 public override System.Type MappedClass 89 { 90 get { return typeof(DynamicTestModel); } 91 } 92 93 public override EntityMode EntityMode 94 { 95 get { return EntityMode.Map; } 96 } 97 98 protected override IGetter BuildPropertyGetter(NHibernate.Mapping.Property mappedProperty, PersistentClass mappedEntity) 99 {100 return BuildPropertyAccessor(mappedProperty).GetGetter(null, mappedProperty.Name);101 }102 103 104 105 private IPropertyAccessor BuildPropertyAccessor(NHibernate.Mapping.Property property)106 {107 return Accessor;108 }109 110 protected override ISetter BuildPropertySetter(NHibernate.Mapping.Property mappedProperty, PersistentClass mappedEntity)111 {112 return BuildPropertyAccessor(mappedProperty).GetSetter(null, mappedProperty.Name);113 }114 115 protected override IInstantiator BuildInstantiator(PersistentClass mappingInfo)116 {117 return new DynamicModelMapInstantiator(mappingInfo); // new DynamicMapInstantiator(mappingInfo);118 }119 120 protected override IProxyFactory BuildProxyFactory(PersistentClass mappingInfo, IGetter idGetter,121 ISetter idSetter)122 {123 IProxyFactory pf = new MapProxyFactory();124 try125 {126 //TODO: design new lifecycle for ProxyFactory127 pf.PostInstantiate(EntityName, null, null, null, null, null);128 }129 catch (HibernateException he)130 {131 log.Warn("could not create proxy factory for:" + EntityName, he);132 pf = null;133 }134 return pf;135 }136 }137 }

 

DynamicInterceptor

1 using NHibernate; 2 using NHibernate.Mapping; 3 using System.Collections.Generic; 4  5 namespace DynamicTableTest.DynamicTable 6 { 7     public class DynamicInterceptor : EmptyInterceptor 8     { 9         private readonly string entityName;10         private readonly HashSet
isInstanceEntityNames = new HashSet
();11 12 public DynamicInterceptor()13 {14 entityName = null;15 }16 17 public DynamicInterceptor(PersistentClass mappingInfo)18 {19 entityName = mappingInfo.EntityName;20 isInstanceEntityNames.Add(entityName);21 if (mappingInfo.HasSubclasses)22 {23 foreach (PersistentClass subclassInfo in mappingInfo.SubclassClosureIterator)24 isInstanceEntityNames.Add(subclassInfo.EntityName);25 }26 }27 28 public override string GetEntityName(object entity)29 {30 var dynamicEntity = entity as DynamicTestModel;31 if (dynamicEntity == null) {32 return base.GetEntityName(entity);33 }34 else35 {36 return dynamicEntity.EntityName;37 }38 }39 }40 }

 

DynamicModelAccesser
1 using NHibernate.Engine;  2 using NHibernate.Properties;  3 using System;  4 using System.Collections;  5 using System.Reflection;  6   7 namespace DynamicTableTest.DynamicTable  8 {  9     public class DynamicModelAccesser : IPropertyAccessor 10     { 11         private static readonly string CUSTOM_PROPERTY_NAME = "CustomProperties"; 12         private static readonly string AUTO_ID_NAME = "auto_id"; 13  14         public IGetter GetGetter(System.Type theClass, string propertyName) 15         { 16             return new DynamicGetter(propertyName); 17         } 18  19         public ISetter GetSetter(System.Type theClass, string propertyName) 20         { 21             return new DynamicSetter(propertyName); 22         } 23  24         public bool CanAccessThroughReflectionOptimizer 25         { 26             get { return false; } 27         } 28  29         [Serializable] 30         public sealed class DynamicSetter : ISetter 31         { 32             private readonly string name; 33  34             internal DynamicSetter(string name) 35             { 36                 this.name = name; 37             } 38  39             public MethodInfo Method 40             { 41                 get { return null; } 42             } 43  44             public string PropertyName 45             { 46                 get { return null; } 47             } 48  49             public void Set(object target, object value) 50             { 51                 if (CUSTOM_PROPERTY_NAME.Equals(name)) 52                 { 53                     (target as DynamicTestModel).CustomProperties = (IDictionary)value; 54                 } 55                 else if (AUTO_ID_NAME.Equals(name)) 56                 { 57                     (target as DynamicTestModel).auto_id = value as string; 58                 }  59          else  60          { 61                   (target as DynamicTestModel).CustomProperties[name] = value;  62                } 63             } 64         } 65  66         [Serializable] 67         public sealed class DynamicGetter : IGetter 68         { 69             private readonly string name; 70  71             internal DynamicGetter(string name) 72             { 73                 this.name = name; 74             } 75  76             public MethodInfo Method 77             { 78                 get { return null; } 79             } 80  81             public object GetForInsert(object owner, IDictionary mergeMap, ISessionImplementor session) 82             { 83                 return Get(owner); 84             } 85  86             public string PropertyName 87             { 88                 get { return null; } 89             } 90  91             public System.Type ReturnType 92             { 93                 get { return typeof(object); } 94             } 95  96             public object Get(object target) 97             { 98                 if (CUSTOM_PROPERTY_NAME.Equals(name)) 99                 {100                     return (target as DynamicTestModel).CustomProperties;101                 }102                 else if (AUTO_ID_NAME.Equals(name))103                 {104                     return (target as DynamicTestModel).auto_id;105                 }106                 return (target as DynamicTestModel).CustomProperties[name];107             }108         }109     }110 }

 

模板hbm.xml

1 
2
10 11
12
13
14
15
16
17
18
19

 

最后是测试代码,QueryOver中where在这里会有问题,改用hql语句实现了

1 using DynamicTableTest.DynamicTable; 2 using System; 3 using System.Linq; 4  5 namespace DynamicTableTest 6 { 7     class Program 8     { 9         static void Main(string[] args)10         {11             DynamicModelMethod();12 13             Console.Read();14         }15 16         private static void DynamicModelMethod()17         {18             var entityName = "Test_Role";19             var columnName = "Name";20             var columnRole = "Role";21             var columnCreateTime = "Create_Time";22 23             var dynamicEntity = new DynamicTestModel(entityName);24             var name = Guid.NewGuid().ToString();25             dynamicEntity.SetValueOfCustomField(columnName, name);26             dynamicEntity.SetValueOfCustomField(columnRole, 31);27             dynamicEntity.SetValueOfCustomField(columnCreateTime, DateTime.Now);28 29             MappingManager.UpdateClassMapping(dynamicEntity);30             HibernateUtil.Instance.Reset();31 32             var session = HibernateUtil.Instance.CurrentSession;33 34             var trans = session.BeginTransaction();35             try36             {37                 //add38                 var id = session.Save(entityName, dynamicEntity);39                 Console.WriteLine("first name: " + name);40 41                 //get42                 var role = (DynamicTestModel)session.Get(entityName, id);43                 var storedName = role.GetValueOfCustomField(columnName);44                 Console.WriteLine("second name: "+storedName);45 46                 //update47                 var newName = Guid.NewGuid().ToString();48                 role.SetValueOfCustomField(columnName, newName);49                 session.SaveOrUpdate(entityName, role);50 51                 //get 52                 role = (DynamicTestModel)session.Get(entityName, id);53                 storedName = role.GetValueOfCustomField(columnName);54                 Console.WriteLine("third name: " + storedName);55 56                 //delete57                 session.Delete(entityName, role);58                 role = (DynamicTestModel)session.Get(entityName, id);59                 Console.WriteLine(role == null);60                 61                 var roles = session.QueryOver
(entityName).List();62 foreach (var roleItem in roles)63 {64 Console.WriteLine(roleItem.ToString());65 }66 Console.WriteLine("###########################################");67 roles = session.CreateQuery(string.Format("from {0} where {1}='{2}'", entityName, columnName, "abc")).Enumerable
().ToList();68 69 foreach (var roleItem in roles)70 {71 Console.WriteLine(roleItem.ToString());72 }73 74 trans.Commit();75 }76 catch (Exception ex)77 {78 trans.Rollback();79 Console.WriteLine(ex.ToString());80 }81 }82 }83 }

Over!

转载于:https://www.cnblogs.com/zdalh/p/3811728.html

你可能感兴趣的文章
Netty线程模型理解
查看>>
netty解决tcp粘包和拆包问题
查看>>
Netty速成:基础+入门+中级+高级+源码架构+行业应用
查看>>
Netty遇到TCP发送缓冲区满了 写半包操作该如何处理
查看>>
netty(1):NIO 基础之三大组件和ByteBuffer
查看>>
Netty:ChannelPipeline和ChannelHandler为什么会鬼混在一起?
查看>>
Netty:原理架构解析
查看>>
Network Dissection:Quantifying Interpretability of Deep Visual Representations(深层视觉表征的量化解释)
查看>>
Network Sniffer and Connection Analyzer
查看>>
Network 灰鸽宝典【目录】
查看>>
Networkx写入Shape文件
查看>>
NetworkX系列教程(11)-graph和其他数据格式转换
查看>>
Networkx读取军械调查-ITN综合传输网络?/读取GML文件
查看>>
NetworkX:是否为每个节点添加超链接?
查看>>
network小学习
查看>>
Netwox网络工具使用详解
查看>>
Net与Flex入门
查看>>
Net任意String格式转换为DateTime类型
查看>>
net包之IPConn
查看>>
net发布的dll方法和类显示注释信息(字段说明信息)[图解]
查看>>