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);

浙公网安备 33010602011771号