Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在linq到sql中动态设置tableAttribute映射_C#_Sql_Linq_Mapping - Fatal编程技术网

C# 在linq到sql中动态设置tableAttribute映射

C# 在linq到sql中动态设置tableAttribute映射,c#,sql,linq,mapping,C#,Sql,Linq,Mapping,我想知道是否可以为linq类动态设置表映射: [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Comfort 0601$Contact]")] public partial class Contact : INotifyPropertyChanging, INotifyPropertyChanged { ... 我想动态或以编程方式更改它的原因是因为我使用的数据库是由Navision创建的

我想知道是否可以为linq类动态设置表映射:

    [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Comfort 0601$Contact]")]
    public partial class Contact : INotifyPropertyChanging, INotifyPropertyChanged
    {
     ...
我想动态或以编程方式更改它的原因是因为我使用的数据库是由Navision创建的。在这些表中,有这些表所属的公司名称的前缀。因此,我希望能够更改前缀

    [global::System.Data.Linq.Mapping.TableAttribute(Name = "dbo.["+SPResources.Database.Company+"$Contact]")]
惠特公司为:

    public const string Company = "Comfort 0601";
我已经试过了,但只有当我将Company声明为常量时,它才会起作用

公司之间的表格结构相同。只需更改名称和内容


我希望有人能给我一些建议。我也不确定这是否可行。

您可以使用自定义为每个实体生成代码。您无法在运行时动态应用属性,因此这是最好的选择。

如果您想先使用代码,您可以使用
ToTable()
方法在运行时配置数据库表(请参见“更改数据库表名”下)。例如,在一个
OnModelCreating()
重写您的DbContext派生函数中:

string company = "Comfort 0601";
modelBuilder.Entity<Contact>().ToTable(company + "Contact");
modelBuilder.Entity<....
modelBuilder.Entity<....
string company=“Comfort 0601”;
modelBuilder.Entity().ToTable(公司+联系人);

modelBuilder.EntityBrian和Gert的答案是这个问题的可能解决方案。但是在运行时更改映射是不可能的(正如Brian提到的)

随着项目的进展,我们决定,如果我们需要另一个公司名称(这意味着该构建是为不同的客户提供的),我们只需重新构建项目。该决定使以下解决方案成为可能:

我们注释掉了Visual Studio生成的原始映射:

//[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[Comfort 0601$Contact]")]
    public partial class Contact : INotifyPropertyChanging, INotifyPropertyChanged
    {
    ...
因为每个Linq类都有自己的分部类,所以我们在自己的类的顶部添加了修改后的映射:

[global::System.Data.Linq.Mapping.TableAttribute(Name = "dbo.["+SPResources.Database.Company+"$Contact]")]
public partial class Contact
{
我们公司将在哪里:

public const string Company = "Comfort 0601";
如果需要为不同的公司重建,我们只需更改公司变量

注意:只有在VS中不更改*.dbml文件时,此选项才能正常工作。如果更改,VS将自动撤消更改


编辑:随着时间的推移,我开始深入研究实体框架,我找到了一个更具体、更合适的解决方案来解决这个问题:

认为添加表前缀的正确解决方案是使用SQL Server 2005(或更高版本),然后为每个所需的前缀创建一个db用户,并将每个db用户的默认模式从“dbo”更改为唯一的模式

另一个解决方案是扩展现有DataContext,使其能够在运行时“更正”MappingSource:

[Table]  // Look no name
public class DbRecord
{
    [Column(IsPrimaryKey=true)]
    public long Id { get; set; }
}

CustomDataContext.UpdateCustomTable(typeof(DbRecord), "DbTable");

using (CustomDataContext dc = new CustomDataContext(dbConnection))
{
    Table<DbRecord> dbTable = dc.GetTable<DbRecord>();
    var query = from item in dbTable;
}
[Table]//找不到名字
公共类数据库记录
{
[列(IsPrimaryKey=true)]
公共长Id{get;set;}
}
UpdateCustomTable(typeof(DbRecord),“DbTable”);
使用(CustomDataContext dc=new CustomDataContext(dbConnection))
{
Table dbTable=dc.GetTable();
var query=dbTable中的from项;
}
这是自定义DataContext(我想可以很容易地将其更改为向现有表名添加前缀)(如果在多线程环境中,则用ConcurrentDictionary替换Dictionary):

公共类CustomDataContext:DataContext { 静态CustomMappingSource_sharedMappingSource=新CustomMappingSource(); 公共静态void UpdateCustomTable(类型rowType,字符串tableName) { _sharedMappingSource.UpdateCustomTable(行类型,表名); } 公共CustomDataContext(System.Data.IDbConnection连接):基本(连接,_sharedMappingSource){} 公共CustomDataContext(字符串fileOrServerOrConnection):基(fileOrServerOrConnection,_sharedMappingSource){} } 内部类CustomMappingSource:MappingSource { AttributeMappingSource mapping=新的AttributeMappingSource(); 字典_customTableNames=新字典(); public void UpdateCustomTable(类型rowType,字符串tableName) { if(string.IsNullOrEmpty(tableName)) 抛出新的ArgumentNullException(“TableName”); _customTableNames[rowType]=表名; } 受保护的重写元模型CreateModel(类型dataContextType) { 元模型oldmodel=mapping.GetModel(dataContextType); CustomMetaModel newmodel=新CustomMetaModel(旧模型,_customTableNames); 返回新模型; } } 内部类CustomMetaModel:MetaModel { 元模型; 字典_customtables=新字典(); 字典_tableNames=新字典(); 公共CustomMetaModel(MetaModel orgmodel、字典表名) { _orgmodel=orgmodel; _表名=表名; } 公共重写元类型GetMetaType(类型类型) { 元表元表; if(_customtables.TryGetValue(类型,out元表)) 返回metaTable.RowType; 其他的 return _orgmodel.GetMetaType(type); } 公共重写元表GetTable(类型rowType) { 元表自定义元表; if(_customtables.TryGetValue(行类型,out customMetaTable)) 返回customMetaTable; if(_tableNames.ContainsKey(rowType)) { MetaTable orgtable=_orgmodel.GetTable(行类型); 元类型orgrowtype=orgtable.RowType; CustomMetaType newRowType=新的CustomMetaType(orgrowtype,this); _添加(rowType,newcustommetatable(orgtable,this,newRowType,_tableNames[rowType]); newRowType.MetaTable=_customtables[rowType]; 返回newRowType.MetaTable; } return _orgmodel.GetTable(rowType); } #区域元模型正向 公共重写类型ContextType{get{return}orgmodel.ContextType;} 公共重写字符串DatabaseName{get{return}orgmodel.DatabaseName;} 公共重写MappingSource MappingSource{get{return}\u orgmodel.MappingSource;} 公共重写类型ProviderType{get{return}\u orgmodel.ProviderType;} 公共图书馆
public class CustomDataContext : DataContext
{
    static CustomMappingSource _sharedMappingSource = new CustomMappingSource();

    public static void UpdateCustomTable(Type rowType, string tableName)
    {
        _sharedMappingSource.UpdateCustomTable(rowType, tableName);
    }

    public CustomDataContext(System.Data.IDbConnection connection) : base(connection, _sharedMappingSource) { }
    public CustomDataContext(string fileOrServerOrConnection) : base(fileOrServerOrConnection, _sharedMappingSource) { }
}

internal class CustomMappingSource : MappingSource
{
    AttributeMappingSource mapping = new AttributeMappingSource();

    Dictionary<Type, string> _customTableNames = new Dictionary<Type, string>();

    public void UpdateCustomTable(Type rowType, string tableName)
    {
        if (string.IsNullOrEmpty(tableName))
            throw new ArgumentNullException("TableName");

        _customTableNames[rowType] = tableName;
    }

    protected override MetaModel CreateModel(Type dataContextType)
    {
        MetaModel oldmodel = mapping.GetModel(dataContextType);
        CustomMetaModel newmodel = new CustomMetaModel(oldmodel, _customTableNames);
        return newmodel;
    }
}

internal class CustomMetaModel : MetaModel
{
    MetaModel _orgmodel;

    Dictionary<Type, MetaTable> _customtables = new Dictionary<Type, MetaTable>();
    Dictionary<Type, string> _tableNames = new Dictionary<Type, string>();

    public CustomMetaModel(MetaModel orgmodel, Dictionary<Type, string> tableNames)
    {
        _orgmodel = orgmodel;
        _tableNames = tableNames;
    }

    public override MetaType GetMetaType(Type type)
    {
        MetaTable metaTable;
        if (_customtables.TryGetValue(type, out metaTable))
            return metaTable.RowType;
        else
            return _orgmodel.GetMetaType(type);
    }
    public override MetaTable GetTable(Type rowType)
    {
        MetaTable customMetaTable;
        if (_customtables.TryGetValue(rowType, out customMetaTable))
            return customMetaTable;

        if (_tableNames.ContainsKey(rowType))
        {
            MetaTable orgtable = _orgmodel.GetTable(rowType);
            MetaType orgrowtype = orgtable.RowType;
            CustomMetaType newRowType = new CustomMetaType(orgrowtype, this);
            _customtables.Add(rowType, new CustomMetaTable(orgtable, this, newRowType, _tableNames[rowType]));
            newRowType.MetaTable = _customtables[rowType];
            return newRowType.MetaTable;
        }

        return _orgmodel.GetTable(rowType);
    }

    #region MetaModel Forwards
    public override Type ContextType { get { return _orgmodel.ContextType; } }
    public override string DatabaseName { get { return _orgmodel.DatabaseName; } }
    public override MappingSource MappingSource { get { return _orgmodel.MappingSource; } }
    public override Type ProviderType { get { return _orgmodel.ProviderType; } }
    public override MetaFunction GetFunction(System.Reflection.MethodInfo method) { return _orgmodel.GetFunction(method); }
    public override IEnumerable<MetaFunction> GetFunctions() { return _orgmodel.GetFunctions(); }
    public override IEnumerable<MetaTable> GetTables() { return _orgmodel.GetTables(); }
    #endregion
}

internal class CustomMetaTable : MetaTable
{
    MetaTable _orgtable;
    MetaModel _metamodel;
    MetaType _rowtype;
    string _tableName;

    public CustomMetaTable(MetaTable orgtable, MetaModel metamodel, MetaType rowtype, string tableName)
    {
        _orgtable = orgtable;
        _metamodel = metamodel;
        _rowtype = rowtype;
        _tableName = tableName;
    }

    public override MetaModel Model { get { return _metamodel; } }
    public override MetaType RowType { get { return _rowtype; } }
    public override string TableName { get { return _tableName; } }

    #region MetaTable Forwards
    public override System.Reflection.MethodInfo DeleteMethod { get { return _orgtable.DeleteMethod; } }
    public override System.Reflection.MethodInfo InsertMethod { get { return _orgtable.InsertMethod; } }
    public override System.Reflection.MethodInfo UpdateMethod { get { return _orgtable.UpdateMethod; } }
    #endregion
}

internal class CustomMetaType : MetaType
{
    MetaType _orgtype;
    MetaModel _metamodel;

    public MetaTable MetaTable { get; set; }

    public CustomMetaType(MetaType orgtype, MetaModel metamodel)
    {
        _orgtype = orgtype;
        _metamodel = metamodel;
    }

    public override MetaTable Table { get { return MetaTable; } }
    public override MetaModel Model { get { return _metamodel; } }

    #region MetaType Forwards
    public override System.Collections.ObjectModel.ReadOnlyCollection<MetaAssociation> Associations { get { return _orgtype.Associations; } }
    public override bool CanInstantiate { get { return _orgtype.CanInstantiate; } }
    public override System.Collections.ObjectModel.ReadOnlyCollection<MetaDataMember> DataMembers { get { return _orgtype.DataMembers; } }
    public override MetaDataMember DBGeneratedIdentityMember { get { return _orgtype.DBGeneratedIdentityMember; } }
    public override System.Collections.ObjectModel.ReadOnlyCollection<MetaType> DerivedTypes { get { return _orgtype.DerivedTypes; } }
    public override MetaDataMember Discriminator { get { return _orgtype.Discriminator; } }
    public override bool HasAnyLoadMethod { get { return _orgtype.HasAnyLoadMethod; } }
    public override bool HasAnyValidateMethod { get { return _orgtype.HasAnyValidateMethod; } }
    public override bool HasInheritance { get { return _orgtype.HasInheritance; } }
    public override bool HasInheritanceCode { get { return _orgtype.HasInheritanceCode; } }
    public override bool HasUpdateCheck { get { return _orgtype.HasUpdateCheck; } }
    public override System.Collections.ObjectModel.ReadOnlyCollection<MetaDataMember> IdentityMembers { get { return _orgtype.IdentityMembers; } }
    public override MetaType InheritanceBase { get { return _orgtype.InheritanceBase; } }
    public override object InheritanceCode { get { return _orgtype.InheritanceCode; } }
    public override MetaType InheritanceDefault { get { return _orgtype.InheritanceDefault; } }
    public override MetaType InheritanceRoot { get { return _orgtype.InheritanceRoot; } }
    public override System.Collections.ObjectModel.ReadOnlyCollection<MetaType> InheritanceTypes { get { return _orgtype.InheritanceTypes; } }
    public override bool IsEntity { get { return _orgtype.IsEntity; } }
    public override bool IsInheritanceDefault { get { return _orgtype.IsInheritanceDefault; } }
    public override string Name { get { return _orgtype.Name; } }
    public override System.Reflection.MethodInfo OnLoadedMethod { get { return _orgtype.OnLoadedMethod; } }
    public override System.Reflection.MethodInfo OnValidateMethod { get { return _orgtype.OnValidateMethod; } }
    public override System.Collections.ObjectModel.ReadOnlyCollection<MetaDataMember> PersistentDataMembers { get { return _orgtype.PersistentDataMembers; } }
    public override Type Type { get { return _orgtype.Type; } }
    public override MetaDataMember VersionMember { get { return _orgtype.VersionMember; } }
    public override MetaDataMember GetDataMember(System.Reflection.MemberInfo member) { return _orgtype.GetDataMember(member); }
    public override MetaType GetInheritanceType(Type type) { return _orgtype.GetInheritanceType(type); }
    public override MetaType GetTypeForInheritanceCode(object code) { return _orgtype.GetTypeForInheritanceCode(code); }
    #endregion
}