Ask a question
Some time ago, in the blog Park to see a friend, asked how to implement the dynamic table name. We all know that an entity class is reflected in the table and should be written like this:
[Table(Name = "User")]
class User
{
[Column]
public int ID;
[Column]
public string Name;
}
Obviously, the table name here is written dead, and sometimes we may want to add a prefix or suffix to different table names, for example:
Tt_user,aa_user,user1, User2.
Analyze problems
To solve this problem, first we need to understand a problem, DataContext is how to map the entity to the table, in fact, it is to use the information provided by Mappingsource to map. To solve the problem above, I just need to refactor a class that inherits from Mappingsource.
Solve the problem
The code is as follows:
Using System;
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;
Using System.Text;
Using System.Xml.Schema; Namespace Alinq.mapping {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.ma
Ppingsource = (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.getmetatabl
ename!= 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, Culture
Info.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.g
Etfunctions (); 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 to New Dynamicattributedmetamodel (this, datacontexttype);
} [Table (Name = "User")] class User {[Column] public int ID;
[Column] public string Name; Class Program {static void Main (string[] args) {var mappingsource = new Dynamicmap
Pingsource ();
int i = 0;
Mappingsource.getmetatablename = delegate (type type) { var att = type. GetCustomAttributes (typeof (Tableattribute), true).
Single () as Tableattribute;
Debug.Assert (att!= null); Return ATT.
Name + i;
};
var constr = @ "Data source=notebook\sqlexpress;initial catalog=demodatacontext;integrated security=true";
var context = new DataContext (Constr, mappingsource) {Log = console.out};
i = 1; Context. Gettable<user> (). Select (o => o).
ToList ();
i = 2; Context. Gettable<user> (). Select (o => o).
ToList (); }
}
}