LinqToSQL下實(shí)現(xiàn)動(dòng)態(tài)表名的映射

字號(hào):

提出問(wèn)題
    前段時(shí)間,在博客園里看到有位朋友,問(wèn)如何實(shí)現(xiàn)在動(dòng)態(tài)表名。我們都知道,把一個(gè)實(shí)體類(lèi)映謝到表里,應(yīng)該這樣寫(xiě):
    [Table(Name="User")]
    classUser
    {
    [Column]
    publicintID;
    [Column]
    publicstringName;
    }
    很明顯,這里的表名是寫(xiě)死的,有些時(shí)候,我們可能要根據(jù)不同的情況實(shí)現(xiàn)不同的表名里加個(gè)前綴或者后綴,例如:
    tt_User,aa_User,User1、User2。
    分析問(wèn)題
    要解決這個(gè)問(wèn)題,首先我們就要明白一個(gè)問(wèn)題,DataContext是如何將實(shí)體到表的映射的,事實(shí)上,它是例用MappingSource提供的信息來(lái)進(jìn)行映射的。要解決上面的問(wèn)題,我就是需要重新構(gòu)一個(gè)繼承于MappingSource的類(lèi)。
    解決問(wèn)題
    代碼如下:
    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);
    }
    publicoverrideIEnumerableGetTables()
    {
    returnsource.GetTables();
    } publicoverrideIEnumerableGetFunctions()
    {
    returnsource.GetFunctions();
    }
    publicoverrideMetaTypeGetMetaType(Typetype)
    {
    returnsource.GetMetaType(type);
    }
    publicoverrideMappingSourceMappingSource
    {
    get{returnsource.MappingSource;}
    }
    publicoverrideTypeContextType
    {
    get{returnsource.ContextType;}
    }
    publicoverridestringDatabaseName
    {
    get{returnsource.DatabaseName;}
    }
    publicoverrideTypeProviderType
    {
    get{returnsource.ProviderType;}
    }
    }
    publicFuncGetMetaTableName;
    protectedoverrideMetaModelCreateModel(TypedataContextType)
    {
    if(dataContextType==null)
    {
    thrownewArgumentNullException("dataContextType");
    }
    returnnewDynamicAttributedMetaModel(this,dataContextType);
    }
    }
    [Table(Name="User")]
    classUser
    {
    [Column]
    publicintID;
    [Column]
    publicstringName;
    }
    classProgram
    {
    staticvoidMain(string[]args)
    {
    varmappingSource=newDynamicMappingSource();
    inti=0;
    mappingSource.GetMetaTableName=delegate(Typetype)
    {
    varatt=type.GetCustomAttributes(typeof(TableAttribute),true).Single()
    asTableAttribute;
    Debug.Assert(att!=null);
    returnatt.Name+i;
    };
    varconstr=@"DataSource=NOTEBOOKSQLEXPRESS;InitialCatalog=DemoDataContext;IntegratedSecurity=True";
    varcontext=newDataContext(constr,mappingSource){Log=Console.Out};
    i=1;
    context.GetTable().Select(o=>o).ToList();
    i=2;
    context.GetTable().Select(o=>o).ToList();
    }
    }
    }