项目场景:
刚开始使用的方法是:针对netcore3.1中一个实体对应多张数据表的问题,重写MappingSource中的实体名称和数据表明映射的函数部分
新建类DynamicMappingSource
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 BackEnd_waterinfo.Models
{
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);
}
}
}
新建类
public static DBContext getData(int i)
{
var mappingSource = new DynamicMappingSource();
mappingSource.GetMetaTableName = delegate (Type type)
{
return "WA_H_X" + i;
};
return new DataContext(Config.sqlPath,mappingSource);
}
问题描述
例如:通过以上方法发现最后能够实现对于动态数据库表的连接,但是查询到的数据全是null,虽然查询到的数据条数是对的,但是数据内容都不对。
原因分析:
例如:查询数据都是null的原因还是不太清楚,应该是因为在底层映射的时候没有映射好,应该是哪个方法重写给忽略了,不过这个问题算是解决了。
解决方案:
新建类,使用原生sql语句进行数据库的增删改查操作。
public class HistorySqlConnectTool
{
public static List<WA_H_X> getData(int i)
{
// var mappingSource = new DynamicMappingSource();
/*mappingSource.GetMetaTableName = delegate (Type type)
{
return "WA_H_X" + i;
};*/
var table = "WA_H_X" + i;
//Console.WriteLine(table);
var context = new DataContext(Config.sqlPath);
try
{
var result = context.ExecuteQuery<WA_H_X>(@"select * from " + table).ToList();
return result;
}
catch (Exception ex)
{
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
logger.Error(ex.ToString());
return new List<WA_H_X>();
}
}
}
最后一个实体成功映射到多张数据表中