提出问题
前段时间,在博客园里看到有位朋友,问如何实现在动态表名。我们都知道,把一个实体类映谢到表里,应该这样写:
[Table(Name="User")]
classUser
{
[Column]
publicintID;
[Column]
publicstringName;
}
很明显,这里的表名是写死的,有些时候,我们可能要根据不同的情况实现不同的表名里加个前缀或者后缀,例如:
tt_User,aa_User,User1、User2。
分析问题
要解决这个问题,首先我们就要明白一个问题,DataContext是如何将实体到表的映射的,事实上,它是例用MappingSource提供的信息来进行映射的。要解决上面的问题,我就是需要重新构一个继承于MappingSource的类。
解决问题
代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Data.Linq;
usingSystem.Data.Linq.Mapping;
usingSystem.Diagnostics;
usingSystem.Globalization;
usingSystem.Linq;
usingSystem.Reflection;
usingSystem.Text;
usingSystem.Xml.Schema;
namespaceALinq.Mapping
{
classDynamicMappingSource:MappingSource
{
classDynamicAttributedMetaModel:MetaModel
{
privateMetaModelsource;
privateconststringTypeName="System.Data.Linq.Mapping.AttributedMetaModel";
privateDynamicMappingSourcemappingSource;
internalDynamicAttributedMetaModel(MappingSourcemappingSource,TypecontextType)
{
this.mappingSource=(DynamicMappingSource)mappingSource;
varbf=BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.CreateInstance;
varargs=newobject[]{mappingSource,contextType};
source=typeof(DataContext).Assembly.CreateInstance(TypeName,false,bf,null,
args,CultureInfo.CurrentCulture,null)asMetaModel;
Debug.Assert(source!=null);
}
publicoverrideMetaTableGetTable(TyperowType)
{
if(mappingSource.GetMetaTableName!=null)
{
vartypeName="System.Data.Linq.Mapping.AttributedMetaTable";
varbf=BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.CreateInstance;
varattribute=newTableAttribute{Name=mappingSource.GetMetaTableName(rowType)};
varargs=newobject[]{source,attribute,rowType};
varmetaTable=typeof(DataContext).Assembly.CreateInstance(typeName,false,bf,null,
args,CultureInfo.CurrentCulture,null)asMetaTable;
returnmetaTable;
}
returnsource.GetTable(rowType);
}
publicoverrideMetaFunctionGetFunction(MethodInfomethod)
{
returnsource.GetFunction(method);
}
publicoverrideIEnumerable<MetaTable>GetTables()
{
returnsource.GetTables();
}
责任编辑:小草