Entity Framework 6 SQL 没有配置文件的 Server Compact 3.5
Entity Framework 6 SQL Server Compact 3.5 without Config file
我正在尝试使用 Entity Framework 6 使用 EntityFramework.SqlServerCompact.Legacy 6.1.3.
访问 SQL Server Compact 3.5 数据库
我的应用程序是一个 Visual Studio 扩展,我无法向应用程序配置文件添加任何内容。
如果我做一个简单的测试应用程序,我可以毫无问题地连接到数据库。如果我尝试从 class 库访问数据库,它会失败并显示错误消息
Schema specified is not valid. Errors:
ProjectTemplate.ssdl(2,2) : error 0152: No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlServerCe.3.5'. Make sure the provider is registered in the 'entityFramework' section of the application config file. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.
我找到了一些有趣的链接,例如 here and here,但我无法使其正常工作,因为该示例适用于 EF5 或 SQL 服务器(或者我有问题我的眼睛)。
我该怎么做?
我目前正在使用控制台应用程序和 class 库进行测试。控制台应用程序对 Entity Framework 一无所知,只是调用 class 库中的一个方法。
static void Main(string[] args)
{
EFTest t = new EFTest();
t.Test();
}
这是 class 库中的代码。
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:\DotNetTestProjects15\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 提到的 link 中 Ryan Griffith 的回答。
这似乎在我的测试程序的上下文中有效,但我还没有在 Visual Studio 扩展的上下文中尝试过。
据我所知,只有在 AppDomain 中首次加载 DbConfiguration 之前将事件处理程序添加到 DbConfiguration.Loaded 时,此技术才会起作用(我可能无法保证).我还担心它可能对 Visual Studio 或其他 Visual Studio 扩展有副作用。
我正在尝试使用 Entity Framework 6 使用 EntityFramework.SqlServerCompact.Legacy 6.1.3.
访问 SQL Server Compact 3.5 数据库我的应用程序是一个 Visual Studio 扩展,我无法向应用程序配置文件添加任何内容。
如果我做一个简单的测试应用程序,我可以毫无问题地连接到数据库。如果我尝试从 class 库访问数据库,它会失败并显示错误消息
Schema specified is not valid. Errors: ProjectTemplate.ssdl(2,2) : error 0152: No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlServerCe.3.5'. Make sure the provider is registered in the 'entityFramework' section of the application config file. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.
我找到了一些有趣的链接,例如 here and here,但我无法使其正常工作,因为该示例适用于 EF5 或 SQL 服务器(或者我有问题我的眼睛)。
我该怎么做?
我目前正在使用控制台应用程序和 class 库进行测试。控制台应用程序对 Entity Framework 一无所知,只是调用 class 库中的一个方法。
static void Main(string[] args)
{
EFTest t = new EFTest();
t.Test();
}
这是 class 库中的代码。
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:\DotNetTestProjects15\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 提到的 link 中 Ryan Griffith 的回答。
这似乎在我的测试程序的上下文中有效,但我还没有在 Visual Studio 扩展的上下文中尝试过。
据我所知,只有在 AppDomain 中首次加载 DbConfiguration 之前将事件处理程序添加到 DbConfiguration.Loaded 时,此技术才会起作用(我可能无法保证).我还担心它可能对 Visual Studio 或其他 Visual Studio 扩展有副作用。