键“数据源”的值长度超过了“128”的限制

Posted

技术标签:

【中文标题】键“数据源”的值长度超过了“128”的限制【英文标题】:The value's length for key 'data source' exceeds it's limit of '128' 【发布时间】:2016-09-13 21:45:59 【问题描述】:

我知道有人问过here 一个非常相似的问题,但答案对我没有帮助。

我正在使用带有 Oracle.ManagerDataAccess.Client 的 Entity Framework 6。

如果我在 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 中的配置,但是如果我们可以在没有完整客户端的情况下与 oracle 数据库通信,那将是一个很大的好处。

更新

这就是 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 ) ;
  

这两种方法中使用的连接字符串是相同的。

【问题讨论】:

如何在代码中设置连接字符串?我以前从未见过有关连接字符串的错误。 我添加了更多信息。 【参考方案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 中的任何值。

【讨论】:

【参考方案2】:

您不需要任何 Oracle 客户端即可使用 tnsnames.ora 文件。

只需查看this answer(最后一段)ODP.NET 托管驱动程序在哪个文件夹中需要tnsnames.ora,分别。 sqlnet.ora 文件。

您也可以在.config 文件中定义别名,参见Configuring Oracle Data Provider for .NET

【讨论】:

我想避免使用 app.config 文件,因为我想将数据访问封装在类库中,供多个应用程序使用。数据库连接是独立配置和存储的。 您不必使用 app.config 文件,它只是一个选项。通过给定的可能性之一指定 tnsnames.ora 文件的位置,您就完成了。 谢谢,我试了一下,失败了。我会再试一次。 尝试环境变量 TNS_ADMIN,这应该优先于所有其他值 在调试器输出窗口中,我收到很多消息 Exception throw: 'System.Data.SqlClient.SqlException' in System.Data.dll 这让我认为它正在尝试连接到 SQL 服务器和不是甲骨文。 app.config 中带有连接字符串的版本确实指定了提供程序名称,当我只在代码中使用连接字符串时,它就丢失了。我认为它将来自我指定为上下文类的属性的 DBConfiguration。【参考方案3】:

一旦我没有足够的声誉来评论任何问题或答案,我就会在此处发布我的发现。

就我而言,Phill Jollans 的回答几乎解决了。以下细节必须额外完成

我不需要那么多构造函数;在上下文类中,只有构造函数接收连接字符串并将其传递给基类就足够了。 我不得不手动删除 app.config 文件中的 SqlServer 连接字符串提供程序。

上下文很可能试图实例化与 SqlServer 而不是 Oracle 的连接,从而导致该验证引发此异常。 oracle数据源key好像没有这个限制。

【讨论】:

【参考方案4】:

几天前我遇到了同样的问题,上下文试图实例化与 SqlServer 而不是 Oracle 的连接。

我不得不对下面的代码进行更改:

services.AddDbContext<ManagerContext>(options =>      options.UseSqlServer(configuration.GetConnectionString("cnnFinacle")),
                       ServiceLifetime.Transient);

我通过将 UseSqlServer 更改为 UseOracle 来修复它

请注意,此上下文位于 dotnet core WorkerService 上

【讨论】:

以上是关于键“数据源”的值长度超过了“128”的限制的主要内容,如果未能解决你的问题,请参考以下文章

解决128位秘钥长度限制的方法

修改Mysql索引长度限制

cookie超过最大长度限制如何解决

字符串的长度超过 maxJsonLength 属性上设置的值

MVC中JSON字符长度超出限制

old BIOSes限制