程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Linq To SQL下實現動態表名的映射

Linq To SQL下實現動態表名的映射

編輯:關於.NET

提出問題

前段時間,在博客園裡看到有位朋友,問如何實現在動態表名。我們都知道,把一個實體類映謝到表 裡,應該這樣寫:

[Table(Name = "User")]
class User
{
[Column]
public int ID;
[Column]
public string Name;
}

很明顯,這裡的表名是寫死的,有些時候,我們可能要根據不同的情況實現不同的表名 裡加個前綴或者後綴,例如:

tt_User,aa_User,User1、User2。

分析問題

要解決這個問題,首先我們就要明白一個問題,DataContext是如何將實體到表的映射的,事實上,它 是例用MappingSource提供的信息來進行映射的。要解決上面的問題,我就是需要重新構一個繼承於 MappingSource的類。

解決問題

代碼如下:

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.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(Name = "User")]
    class User
    {
        [Column]
        public int ID;
        [Column]
        public string Name;
    }
    class Program
    {
        static void Main(string[] args)
        {
            var mappingSource = new DynamicMappingSource();
            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();
        }
    }
}

把運行後的結果給大家看一下:

從上圖可以看到,表名已經由原來的User分別變為了User1和User2。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved