簡體   English   中英

C#交互式窗口中的實體框架Code-First(Oracle)

[英]Entity framework Code-First in c# interactive window (Oracle)

我正在嘗試使用c#交互式窗口來快速測試一些代碼。 嘗試測試與DbContext(EF6)相關的代碼時遇到麻煩。

我知道我需要傳遞連接字符串,因為交互式窗口不會加載App.config文件,因此我已經覆蓋了指定連接字符串的構造函數。

我還必須說,我正在將ODB.NET提供程序與Oracle數據庫一起使用。

這是我要在交互式窗口上運行的代碼:

#r "MyProjPath\bin\Debug\CsCore.EntityDomain.dll"
#r "MyProjPath\bin\Debug\EntityFramework.dll"
#r "MyProjPath\bin\Debug\EntityFramework.SqlServer.dll"
#r "MyProjPath\bin\Debug\Oracle.ManagedDataAccess.dll"
#r "MyProjPath\bin\Debug\Oracle.ManagedDataAccess.EntityFramework.dll"
var ctx = new CsCore.EntityDomain.Pivot.PivotContext("Data Source=MyDataSource;User Id=MyUser;Password=MyPassword;");
ctx.ReconciliationRules.FirstOrDefault()

這是我得到的例外

The underlying provider failed on Open.
  + System.Data.Entity.Core.EntityClient.EntityConnection.Open()
  + System.Data.Entity.Core.Objects.ObjectContext.EnsureConnection(bool)
  + System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction<T>(Func<T>, System.Data.Entity.Infrastructure.IDbExecutionStrategy, bool, bool)
  + System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute<TResult>(Func<TResult>)
  + ObjectQuery<T>.GetResults(Nullable<System.Data.Entity.Core.Objects.MergeOption>)
  + LazyEnumerator<T>.MoveNext()
  + System.Linq.Enumerable.FirstOrDefault<TSource>(IEnumerable<TSource>)
  + System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle<TResult>(IEnumerable<TResult>, System.Linq.Expressions.Expression)
  + System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute<TResult>(System.Linq.Expressions.Expression)
  + System.Data.Entity.Internal.Linq.DbQueryProvider.Execute<TResult>(System.Linq.Expressions.Expression)
  + System.Linq.Queryable.FirstOrDefault<TSource>(IQueryable<TSource>)

我的DbContext看起來像這樣:

public class PivotContext : DbContext
{
    public virtual DbSet<PivotReconciliationRule> ReconciliationRules { get; set; }

    public PivotContext() : this("name=myConnectionStringName")
    {
    }

    public PivotContext(string nameOrConnectionString) : base(nameOrConnectionString)
    {
        Database.SetInitializer<PivotContext>(null);
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema("MYSCHEMA");

        base.OnModelCreating(modelBuilder);
    }
}

我認為原因是我無法指定正確的提供程序。 有人設法通過c#交互窗口使用代碼優先EntityFramework代碼(在oracle上)嗎?

提前謝謝了。

尼古拉

我終於設法使它起作用。

首先,我收到消息“底層提供程序在打開時失敗”。 因為EF無法獲得正確的提供程序和連接工廠。 實際上,它是在嘗試使用SqlServer連接工廠,而不是Oracle的工廠。 在數據庫優先方法中,您可以從EntityConnection創建DbContext,該EntityConnection指定提供程序。 不幸的是,在這種情況下,您似乎還必須提供模型,該模型不適用於代碼優先。

最后我解決了供應商/工廠設置以下的相關信息這篇文章 相應的csx代碼為:

System.Data.Entity.DbConfiguration.Loaded += (_, a) =>
{
    var services = Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices.Instance;
    a.ReplaceService<System.Data.Entity.Core.Common.DbProviderServices>((s, k) => services);
    var factory = new Oracle.ManagedDataAccess.EntityFramework.OracleConnectionFactory();
    a.ReplaceService<System.Data.Entity.Infrastructure.IDbConnectionFactory>((s, k) => factory);
};

這樣做之后,我仍然收到以下錯誤:無法確定類型為'Oracle.ManagedDataAccess.Client.OracleClientFactory'的提供程序工廠的提供程序名稱。 確保已在應用程序配置中安裝或注冊了ADO.NET提供程序。

這是由於OracleClientFactory未與實體框架提供程序相關聯(來自“ entityFramework”部分)。 我無法直接通過代碼執行此操作。 我最終在我的machine.config中添加了“ entityFramework”部分:

configSections的聲明:

<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="oracle.manageddataaccess.client" type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />

configSection的內容:

<entityFramework>
  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
    <parameters>
      <parameter value="mssqllocaldb" />
    </parameters>
  </defaultConnectionFactory>
  <providers>
    <provider invariantName="Oracle.ManagedDataAccess.Client" type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
  </providers>
</entityFramework>

<system.data>
  <DbProviderFactories>
    <remove invariant="Oracle.ManagedDataAccess.Client" />
    <add name="ODP.NET, Managed Driver" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
    ... other staff that was already there
  </DbProviderFactories>
</system.data>

有了這些配置,我終於能夠在c#交互式窗口中使用Oracle代碼優先EF6代碼。

首先,您可以使用App.Config和來自應用程序配置的連接字符串:

var AppConfig = System.Configuration.ConfigurationManager.OpenExeConfiguration(@"bin\Debug\MyApp.exe");
Console.WriteLine($"Loaded {AppConfig.ConnectionStrings.ConnectionStrings.Count} connection strings");

通常,您需要在DbContext中實現OnConfiguring方法(對於Core 2.0中的postgresql,請在此處實現):

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseNpgsql("Host=localhost; Database=mydb; User ID=myuser; Password=mypasswd; Port=0000; ");
}

首次使用上下文時,稱為OnConfiguring

我需要您的DbContext,以幫助您更多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM