簡體   English   中英

沒有配置文件的實體框架6 SQL Server Compact 3.5

[英]Entity Framework 6 SQL Server Compact 3.5 without Config file

我正在嘗試使用EntityFramework.SqlServerCompact.Legacy 6.1.3使用Entity Framework 6訪問SQL Server Compact 3.5數據庫。

我的應用程序是Visual Studio擴展,無法將任何內容添加到應用程序配置文件中。

如果創建一個簡單的測試應用程序,則可以毫無問題地連接到數據庫。 如果我嘗試從類庫訪問數據庫,它將失敗並顯示錯誤消息

指定的架構無效。 錯誤:ProjectTemplate.ssdl(2,2):錯誤0152:未找到具有不變名稱'System.Data.SqlServerCe.3.5'的ADO.NET提供程序的實體框架提供程序。 確保提供程序已在應用程序配置文件的“ entityFramework”部分中注冊。 有關更多信息,請參見http://go.microsoft.com/fwlink/?LinkId=260882

我發現了一些有趣的鏈接,例如在這里此處,但是我無法使它正常工作,因為該示例適用於EF5或SQL Server(或者我不知所措)。

我該怎么做?

我目前正在使用控制台應用程序和類庫進行測試。 控制台應用程序對Entity Framework一無所知,僅在類庫中調用一個方法。

static void Main(string[] args)
{
  EFTest t = new EFTest();
  t.Test();
}

這是類庫中的代碼。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Core.EntityClient;

namespace EF6_SQLCompact_CleanTest_000
{
  public class EFTest
  {
    public void Test()
    {
      try
      {
        // Add an event handler for DbConfiguration.Loaded, which adds our dependency 
        // resolver class to the chain of resolvers.
        System.Data.Entity.DbConfiguration.Loaded += (_, a) => {
          a.AddDependencyResolver(new MyDependencyResolver(), true);
        };

        // Define the provider connection string, specifying the SQL Server Compact 3.5 filename.
        String FileName = @"f:\DotNetTestProjects\2015\CS\SQLCompact35DllTest\SQLCompact35DllTest\ProjectTemplate.sdf";
        String ConnectionString = String.Format("Data Source={0}", FileName);

        // Create the entity framework connection string, specifying the model,
        // the provider and the provider connection string.
        var builder = new EntityConnectionStringBuilder();
        builder.Metadata = @"res://*/ProjectTemplate.csdl|res://*/ProjectTemplate.ssdl|res://*/ProjectTemplate.msl";
        builder.Provider = "System.Data.SqlServerCe.3.5";
        builder.ProviderConnectionString = ConnectionString;

        // Create the entity framework kontext
        Entities Context = new Entities(builder.ToString());

        // Do a trivial query as a test.
        int i = Context.Languages.Count();
        MessageBox.Show(i.ToString());
      }
      catch (Exception e)
      {
        MessageBox.Show(e.Message);
      }
    }
  }

  // Define an additional constructor for the Entities class, so that we can 
  // pass the connection string into the base class DbContext.
  public partial class Entities : DbContext
  {
    public Entities(String ConnectionString)
      : base(ConnectionString)
    {
    }
  }

  class MyDependencyResolver : System.Data.Entity.Infrastructure.DependencyResolution.IDbDependencyResolver
  {
    public object GetService(Type type, object key)
    {
      // Output the service attempting to be resolved along with it's key 
      System.Diagnostics.Debug.WriteLine(string.Format("MyDependencyResolver.GetService({0}, {1})", type.Name, key == null ? "" : key.ToString()));

      if ((type == typeof(System.Data.Common.DbProviderFactory))
           && (key != null)
           && ((string)(key) == "System.Data.SqlServerCe.3.5"))
      {
        return System.Data.SqlServerCe.SqlCeProviderFactory.Instance ;
      }
      else if ((type == typeof(System.Data.Entity.Core.Common.DbProviderServices))
                && (key != null)
                && ((string)(key) == "System.Data.SqlServerCe.3.5"))
      {
        return System.Data.Entity.SqlServerCompact.Legacy.SqlCeProviderServices.Instance ;
      }
      else if ((type == typeof(System.Data.Entity.Infrastructure.IProviderInvariantName))
                && (key is System.Data.SqlServerCe.SqlCeProviderFactory))
      {
        return new MyProviderInvariantName();
      }

      return null;
    }

    public IEnumerable<object> GetServices(Type type, object key)
    {
      return new object[] { GetService(type, key) }.ToList().Where(o => o != null);
    }
  }

  // Implement IProviderInvariantName so that we can return an object when
  // requested in GetService()
  class MyProviderInvariantName : IProviderInvariantName
  {
    public string Name
    {
      get { return "System.Data.SqlServerCe.3.5"; }
    }
  }
}

依賴項解析器基於EricEJ提到的鏈接中Ryan Griffith的回答。

這似乎可以在我的測試程序的上下文中工作,但是我還沒有在Visual Studio Extension的上下文中嘗試過。

據我所知,僅當在AppDomain中首次加載DbConfiguration之前將事件處理程序添加到DbConfiguration.Loaded中時,此技術才有效(我可能無法保證)。 我也擔心它可能會對Visual Studio或其他Visual Studio擴展產生副作用。

暫無
暫無

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

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