0

Я знаю, что задан очень похожий вопрос here, но ответ мне не помог.Длина значения для ключевого «источника данных» превышает его предел «128»

Я использую Entity Framework 6 с Oracle.ManagerDataAccess.Client.

Если я определяю строку подключения в app.config, то соединение работает. Если я указать идентичную строку подключения в коде, то я получаю ошибку

The value's length for key 'data source' exceeds it's limit of '128'. 

, который является правильным.

Это моя строка соединения (с некоторыми именами удалено):

"User Id=xxxxxxxxxxx;Password=xxxx;Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = VS-ORACLE.xxxxxxx.de)(PORT = 1521))) (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = orcl.xxxxxxxx.de)))" 

Я знаю, что есть куча пробелов, которые могут быть удалены, но я до сих пор не собираюсь, чтобы получить строку вниз ниже 128 персонажи.

Как это работает, когда строка подключения находится в app.config, но не тогда, когда она находится в коде?

Есть ли какой-либо трюк, который я могу использовать, выгружая некоторые параметры в другую строку?

Я уже использую объект DBConfiguration. Есть ли способ установить некоторые параметры в этом объекте?

Если я использую полный клиент oracle, я предполагаю, что могу ссылаться на конфигурацию в файле tnsnames.ora, но это было бы большим преимуществом, если бы мы могли разговаривать с базой данных оракула без полного клиента.

Update

Это то, что строка соединения выглядит в app.config

<connectionStrings> 
    <add name="OracleDbContext" providerName="Oracle.ManagedDataAccess.Client" connectionString="User Id=xxxxxxxxxxx;Password=xxxx;Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = VS-ORACLE.xxxxxxxx.de)(PORT = 1521))) (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = orcl.xxxxxxxx.de)))" /> 
</connectionStrings> 

В коде я определил класс контекста следующим образом:

[DbConfigurationType(typeof(OracleDBConfiguration))] 
public class GlobalAttributeContext : DbContext 
{ 
    public DbSet<GlobalAttribute> GlobalAttributes { get; set; } 

    static GlobalAttributeContext() 
    { 
    Database.SetInitializer<GlobalAttributeContext>(null); 
    } 

    public GlobalAttributeContext(string nameOrConnectionString) : base(nameOrConnectionString) 
    { 
    } 

    public GlobalAttributeContext() : this ("Name=OracleDbContext") 
    { 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
    // We have to pass the schema name into the configuration. (Is there a better way?) 
    modelBuilder.Configurations.Add(new GlobalAttribute_Config_Oracle("SchemaName")) ; 
    } 
} 

У меня есть определен класс DbConfiguration следующим образом:

class OracleDBConfiguration : DbConfiguration 
{ 
    public OracleDBConfiguration() 
    { 
    this.SetDefaultConnectionFactory (new System.Data.Entity.Infrastructure.LocalDbConnectionFactory("v12.0")) ; 
    this.SetProviderServices ("Oracle.ManagedDataAccess.Client", Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices.Instance) ; 
    this.SetProviderFactory ("Oracle.ManagedDataAccess.Client", Oracle.ManagedDataAccess.Client.OracleClientFactory.Instance) ; 
    } 
} 

Наконец, я создаю контекст, как это

string ConnectionString = "User Id=xxxxxxxxxxx;Password=xxxx;Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = VS-ORACLE.xxxxxxxx.de)(PORT = 1521))) (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = orcl.xxxxxxx.de)))" ; 

using (var ctx = new GlobalAttributeContext(ConnectionString)) 
{ 
    var globalAttributes = ctx.GlobalAttributes.ToList() ; 
    foreach (GlobalAttribute ga in globalAttributes) 
    { 
    Console.WriteLine ("Name: {0}, Value: {1}", ga.Attribute, ga.Value) ; 
    } 
} 

соединительном строк, используемых в этих двух методов идентичны.

+0

Как вы устанавливаете строку соединения в коде? Я никогда не видел эту ошибку вокруг строк подключения раньше. – bhmahler

+0

Я добавил дополнительную информацию. –

ответ

1

Мой коллега нашел ответ на эту проблему следующим образом:

Добавить другой конструктор класса контекста использовать существующую коллекцию.

public GlobalAttributeContext(DbConnection existingConnection, bool contextOwnsConnection) 
     : base(existingConnection, true) 
{ 
} 

Это полный контекст класс

namespace OracleTestExeConfigAndConnStr 
{ 
    [DbConfigurationType(typeof(OracleDBConfiguration))] 
    public class GlobalAttributeContext : DbContext 
    { 
    public DbSet<GlobalAttribute> GlobalAttributes { get; set; } 

    static GlobalAttributeContext() 
    { 
     Database.SetInitializer<GlobalAttributeContext>(null); 
    } 

    public GlobalAttributeContext() : base("OracleDbContext") 
    { 
    } 

    public GlobalAttributeContext(string nameOrConnectionString) 
      : base(nameOrConnectionString) 
    { 
    } 

    public GlobalAttributeContext(DbConnection existingConnection, bool contextOwnsConnection) 
      : base(existingConnection, true) 
    { 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // We have to pass the schema name into the configuration. (Is there a better way?) 
     modelBuilder.Configurations.Add(new GlobalAttribute_Config_Oracle("SchemaName")) ; 
    } 
    } 
} 

создать соединение с базой данных в качестве отдельного шага и передать соединение в объект контекста.

string connStr = @"User Id=xxxxxxxxxxx;Password=xxxx;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=VS-ORACLE.xxxxxxxx.de)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl.xxxxxxxx.de)))"; 

using (var connection = new OracleConnection() { ConnectionString = connStr }) 
{ 
    connection.Open(); 
    using (var ctx = new GlobalAttributeContext(connection, true)) 
    { 
    var globalAttributes = ctx.GlobalAttributes.ToList(); 
    foreach (GlobalAttribute ga in globalAttributes) 
    { 
     Console.WriteLine("Name: {0}, Value: {1}", ga.Attribute, ga.Value); 
    } 
    } 
} 

Для полноты, это класс DBConfiguration, который указан в качестве атрибута класса контекста.

class OracleDBConfiguration : DbConfiguration 
{ 
    public OracleDBConfiguration() 
    { 
    this.SetDefaultConnectionFactory (new System.Data.Entity.Infrastructure.LocalDbConnectionFactory("v12.0")) ; 
    this.SetProviderServices ("Oracle.ManagedDataAccess.Client", Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices.Instance) ; 
    this.SetProviderFactory ("Oracle.ManagedDataAccess.Client", Oracle.ManagedDataAccess.Client.OracleClientFactory.Instance) ; 
    } 
} 

Этот метод работает из DLL без каких-либо значений в app.config.

0

Вам не нужен клиент Oracle для использования файла tnsnames.ora.

Просто см. this answer (последний абзац), в котором папка Управляемый драйвер ODP.NET ожидает tnsnames.ora, соотв. sqlnet.ora файл.

Вы можете определить псевдоним также в .config файле см Configuring Oracle Data Provider for .NET

+0

Я хочу, чтобы избежать использования файла app.config, потому что я хочу инкапсулировать доступ к данным в библиотеке классов, который будет использоваться несколькими приложениями. Соединение с базой данных настроено и хранится независимо. –

+0

Вам не нужно использовать файл app.config, это просто вариант. Укажите местоположение файла tnsnames.ora по одной из заданных возможностей, и все готово. –

+0

Спасибо, я попробовал это ненадолго и не смог. Я попробую снова. –