Linq to SQL表结构相同表名不同实现动态映射

 

大家从上表可以看出,有4个Table,他们的名称基本一样,除了最后一个字母分别为"A","B","C","D",前面全部都为EventTransportMaster。

而这四个表结构完全一致,如下图所示:

 

 

如果照一般表和实体的映射写法,如下所示:

 [Table(Name = "dbo.EventTransportMasterA")]
 public class LTDTransportTemplateA
 {
 [Column(Name = "TransportID", IsPrimaryKey = true, IsDbGenerated = true)]
 public int TransportID { get; set; }
 [Column]
 public string TransportTitle_EN { get; set; }
 [Column]
 public string TransportTitle_TC { get; set; }
 [Column]
 public string TransportTitle_SC { get; set; }
 [Column]
 public string TransportDesc_EN { get; set; }
 [Column]
 public string TransportDesc_TC { get; set; }
 [Column]
 public string TransportDesc_SC { get; set; }
 [Column]
 public string TransportDetails_EN { get; set; }
 [Column]
 public string TransportDetails_TC { get; set; }
 [Column]
 public string TransportDetails_SC { get; set; }
 [Column]
 public Nullable<int> TransportStatus { get; set; }
 [Column]
 public DateTime LastUpdate { get; set; }
 }

在网上搜索良久,要么就是太深奥,咱们看不懂。要么就不是我想要的东西。终于找到这个文章,不错!

有兴趣可以去http://www.cnblogs.com/ansiboy/archive/2009/02/07/1385840.html 看看。

参照这篇文章,我增加了一个文件DynamicMappingSource.cs,照抄人家代码,能运行,没问题哦!!

usingSystem;

 using System.Collections.Generic;
 using System.Data.Linq;
 using System.Data.Linq.Mapping;
 using System.Diagnostics;
 using System.Globalization;
 using System.Linq;
 using System.Reflection;
   
 namespace pacim
 {
 /// <summary> 
 /// Summary description for DynamicMappingSource 
 /// </summary> 
 public class DynamicMappingSource : MappingSource
 {
 class DynamicAttributedMetaModel : MetaModel
 {
 private MetaModel source;
 private const string TypeName = "System.Data.Linq.Mapping.AttributedMetaModel";
 private DynamicMappingSource mappingSource;
   
 internal DynamicAttributedMetaModel(MappingSource mappingSource, Type contextType)
 {
 this.mappingSource = (DynamicMappingSource)mappingSource;
   
 var bf = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance;
 var args = new object[] { mappingSource, contextType };
 source = typeof(DataContext).Assembly.CreateInstance(TypeName, false, bf, null, args, CultureInfo.CurrentCulture, null) as MetaModel;
 Debug.Assert(source != null);
 }
   
 public override MetaTable GetTable(Type rowType)
 {
 if (mappingSource.GetMetaTableName != null)
 {
 var typeName = "System.Data.Linq.Mapping.AttributedMetaTable";
 var bf = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance;
 var attribute = new TableAttribute { Name = mappingSource.GetMetaTableName(rowType) };
 var args = new object[] { source, attribute, rowType };
 var metaTable = typeof(DataContext).Assembly.CreateInstance(typeName, false, bf, null,
 args, CultureInfo.CurrentCulture, null) as MetaTable;
 return metaTable;
 }
 return source.GetTable(rowType);
 }
   
 public override MetaFunction GetFunction(MethodInfo method)
 {
 return source.GetFunction(method);
 }
   
 public override IEnumerable<MetaTable> GetTables()
 {
 return source.GetTables();
 }
   
 public override IEnumerable<MetaFunction> GetFunctions()
 {
 return source.GetFunctions();
 }
   
 public override MetaType GetMetaType(Type type)
 {
 return source.GetMetaType(type);
 }
   
 public override MappingSource MappingSource
 {
 get { return source.MappingSource; }
 }
   
 public override Type ContextType
 {
 get { return source.ContextType; }
 }
   
 public override string DatabaseName
 {
 get { return source.DatabaseName; }
 }
   
 public override Type ProviderType
 {
 get { return source.ProviderType; }
 }
 }
   
 public Func<Type, string> GetMetaTableName;
   
 protected override MetaModel CreateModel(Type dataContextType)
 {
 if (dataContextType == null)
 {
 throw new ArgumentNullException("dataContextType");
 }
 return new DynamicAttributedMetaModel(this, dataContextType);
 }
   
 }
 }
 
接着就是调用了。首先定义一个通用于四个Table的基类。如下
[Table(Name = "dbo.EventTransportMaster")] //注意这里的TableName,其实只是前缀,并没有对应任何一个具体的表
 public class TransportTableBase
 {
 [Column(Name = "TransportID", IsPrimaryKey = true, IsDbGenerated = true)]
 public int TransportID { get; set; }
 [Column]
 public string TransportTitle_EN { get; set; }
 [Column]
 public string TransportTitle_TC { get; set; }
 [Column]
 public string TransportTitle_SC { get; set; }
 [Column]
 public string TransportDesc_EN { get; set; }
 [Column]
 public string TransportDesc_TC { get; set; }
 [Column]
 public string TransportDesc_SC { get; set; }
 [Column]
 public string TransportDetails_EN { get; set; }
 [Column]
 public string TransportDetails_TC { get; set; }
 [Column]
 public string TransportDetails_SC { get; set; }
 [Column]
 public Nullable<int> TransportStatus { get; set; }
 [Column]
 public DateTime LastUpdate { get; set; }
 }

写了上面的这个基类后,就不需要为四个Table分别写四个对应的类了。

 

接着在网页的后台代码中动态提取这四个表的数据,代码如下:

var mappingSource = newDynamicMappingSource();

   
 string strPrefix = "A"; //因为表名都是一样,仅仅后面分别为"A”,"B”,"C”,"D” 
 mappingSource.GetMetaTableName = delegate(Type type)
 {
 var att = type.GetCustomAttributes(typeof(TableAttribute), true).Single() as TableAttribute;
 return att.Name + strPrefix;
 };
   
 var context = new DataContext(m_strConnString, mappingSource) { Log = Console.Out }; //m_strConnString即为连接数据库的字符串,改成自己的即可。 
 Func<TransportTableBase, TransportTableBase> make = h => new TransportTableBase
 {
 TransportID = h.TransportID,
 TransportTitle_EN = h.TransportTitle_EN,
 TransportTitle_TC = h.TransportTitle_TC,
 TransportTitle_SC = h.TransportTitle_SC,
 TransportDesc_EN = h.TransportDesc_EN,
 TransportDesc_TC = h.TransportDesc_TC,
 TransportDesc_SC = h.TransportDesc_SC,
 TransportDetails_EN = h.TransportDetails_EN,
 TransportDetails_TC = h.TransportDetails_TC,
 TransportDetails_SC = h.TransportDetails_SC,
 TransportStatus = h.TransportStatus,
 LastUpdate = h.LastUpdate,
 };
   
 IEnumerable<TransportTableBase> lstA = (from p in context.GetTable<TransportTableBase>() select make(p)).ToList<TransportTableBase>().OrderByDescending(o => o.TransportID);
 
   
 strPrefix = "B";//因为表名都是一样,仅仅后面分别为"A”,"B”,"C”,"D” 
 IEnumerable<TransportTableBase> lstB = (from p in context.GetTable<TransportTableBase>() select make(p)).ToList<TransportTableBase>().OrderByDescending(o => o.TransportID);
 
   
 strPrefix = "C";//因为表名都是一样,仅仅后面分别为"A”,"B”,"C”,"D” 
 IEnumerable<TransportTableBase> lstC = (from p in context.GetTable<TransportTableBase>() select make(p)).ToList<TransportTableBase>().OrderByDescending(o => o.TransportID);
 
   
 strPrefix = "D";//因为表名都是一样,仅仅后面分别为"A”,"B”,"C”,"D” 
 IEnumerable<TransportTableBase> lstD = (from p in context.GetTable<TransportTableBase>() select make(p)).ToList<TransportTableBase>().OrderByDescending(o => o.TransportID);
 

 

posted @ 2012-01-08 23:32  cicadachina  阅读(214)  评论(0)    收藏  举报