Google をいろいろ調べた結果、興味深いアプローチを見つけました。アイデアは、LINQ エンティティのカスタム マッピング ソースを作成することです。これは、テーブル名のポイントに到達するまで、通常の機能のパススルーにすぎません。
ただし、何らかの理由でTableName
プロパティが実際に呼び出されていないため、その記事の正確なコードは実際には機能していませんでした (1 つまたは 2 つのコンパイル エラーを簡単に修正することは別として)。MetaTable
そのため、オブジェクトに明示的に設定する必要がありました。そして、それはプライベート フィールドであるため、これには反映が必要でした。
私が最終的に得たものは次のとおりです。
カスタム マッピング ソース
public class CustomMappingSource : MappingSource
{
private AttributeMappingSource mapping = new AttributeMappingSource();
protected override MetaModel CreateModel(Type dataContextType)
{
return new CustomMetaModel(mapping.GetModel(dataContextType));
}
}
これは単なるパススルーであり、ここでは興味深いことは何も起きていません。ただし、次のレベルが必要です。
カスタム メタ モデル
public class CustomMetaModel : MetaModel
{
private static CustomAttributeMapping mapping = new CustomAttributeMapping();
private MetaModel model;
public CustomMetaModel(MetaModel model)
{
this.model = model;
}
public override Type ContextType
{
get { return model.ContextType; }
}
public override MappingSource MappingSource
{
get { return mapping; }
}
public override string DatabaseName
{
get { return model.DatabaseName; }
}
public override Type ProviderType
{
get { return model.ProviderType; }
}
public override MetaTable GetTable(Type rowType)
{
return new CustomMetaTable(model.GetTable(rowType), model);
}
public override IEnumerable<MetaTable> GetTables()
{
foreach (var table in model.GetTables())
yield return new CustomMetaTable(table, model);
}
public override MetaFunction GetFunction(System.Reflection.MethodInfo method)
{
return model.GetFunction(method);
}
public override IEnumerable<MetaFunction> GetFunctions()
{
return model.GetFunctions();
}
public override MetaType GetMetaType(Type type)
{
return model.GetMetaType(type);
}
}
繰り返しますが、すべてパススルーです。次のレベルに到達するまで、何も興味深いことはありません:
カスタム メタ テーブル
public class CustomMetaTable : MetaTable
{
private MetaTable table;
private MetaModel model;
public CustomMetaTable(MetaTable table, MetaModel model)
{
this.table = table;
this.model = model;
var tableNameField = this.table.GetType().FindMembers(MemberTypes.Field, BindingFlags.NonPublic | BindingFlags.Instance, (member, criteria) => member.Name == "tableName", null).OfType<FieldInfo>().FirstOrDefault();
if (tableNameField != null)
tableNameField.SetValue(this.table, TableName);
}
public override System.Reflection.MethodInfo DeleteMethod
{
get { return table.DeleteMethod; }
}
public override System.Reflection.MethodInfo InsertMethod
{
get { return table.InsertMethod; }
}
public override System.Reflection.MethodInfo UpdateMethod
{
get { return table.UpdateMethod; }
}
public override MetaModel Model
{
get { return model; }
}
public override string TableName
{
get
{
return table.TableName
.Replace("CRPDTA", ConfigurationManager.AppSettings["BusinessDataSchema"])
.Replace("CRPCTL", ConfigurationManager.AppSettings["ControlDataSchema"]);
}
}
public override MetaType RowType
{
get { return table.RowType; }
}
}
ここで(半)興味深いことが起こります。このTableName
プロパティは、私が見つけた元の記事 (以前にリンク) に基づいて作成したカスタム プロパティのままです。追加する必要があったのは、テーブルにテーブル名を明示的に設定するためのコンストラクターのリフレクションだけでした。
これで、このカスタム マッピングを使用するようにデータ コンテキストの使用法を設定する必要がありました。
using (var db = new BusinessDBContext(ConfigurationManager.ConnectionStrings["BusinessDBConnectionString"].ConnectionString, new CustomAttributeMapping()))