【问题标题】:Using Entity Framework with Sql Server Compact Edition without App.Config additions将实体框架与 Sql Server Compact Edition 一起使用,无需添加 App.Config
【发布时间】:2021-01-13 12:18:02
【问题描述】:

我正在为 Rhinoceros 6 开发一个插件,并且对 Rhinoceros 的 App.Config 文件进行编辑目前看来是不可能的。插件项目的App.Config对Rhinoceros的App.Config没有影响。

出现以下错误消息是因为我无法将提供程序和参数添加到 App.Config 的 entityFramework 部分。

Unable to determine the provider name for provider factory of type 'System.Data.SqlServerCe.SqlCeProviderFactory'. Make sure that the ADO.NET provider is installed or registered in the application config.

我用 NuGet 安装了 EntityFramework.SqlServer.Compact 和 Microsoft.SqlServer.Compact 并检查了引用,一切似乎都很好。

下面是我的代码优先 dbcontext 类:

        public class ModelLocalClipper : DbContext
    { 
        public ModelLocalClipper()
            : base(new SqlCeConnection("Data Source="+ Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+"\\MyDatabase.sdf;Persist Security Info=False;"),
  contextOwnsConnection: true)
        {
            Database.SetInitializer<ModelLocalClipper>(new CreateDatabaseIfNotExists<ModelLocalClipper>());
        }
        
        public DbSet<Scene> Scenes { get; set; }
        public DbSet<LocalProject> LocalProjects { get; set; }
    }

    public class Scene
    {
        public int SceneId { get; set; }
        public string Name { get; set; }

        public int LocalProjectId { get; set; }

        [ForeignKey("LocalProjectId")]
        public virtual LocalProject LocalProject { get; set; }
    }

    public class LocalProject
    {
        public int LocalProjectId { get; set; }
        public string Name { get; set; }

        public virtual ICollection<Scene> Scenes { get; set; }
    }

搜索了一段时间后,我找到了 this solution 并将其转换为用于 SqlCe,如下所示,但它也没有帮助

public class SqlCeProviderInvariantName : IProviderInvariantName
        {
            public static readonly SqlCeProviderInvariantName Instance = new SqlCeProviderInvariantName();
            private SqlCeProviderInvariantName() { }
            public const string ProviderName = "System.Data.SqlServerCe.4.0";
            public string Name { get { return ProviderName; } }
        }

    class SqlCeDbProviderFactoryResolver : IDbProviderFactoryResolver
    {
        public static readonly SqlCeDbProviderFactoryResolver Instance = new SqlCeDbProviderFactoryResolver();
        private SqlCeDbProviderFactoryResolver() { }
        public DbProviderFactory ResolveProviderFactory(DbConnection connection)
        {
            if (connection is SqlCeConnection) return SqlCeProviderFactory.Instance;
            if (connection is EntityConnection) return EntityProviderFactory.Instance;
            return null;
        }
    }

    class SqlCeDbDependencyResolver : IDbDependencyResolver
    {
        public object GetService(Type type, object key)
        {
            if (type == typeof(IProviderInvariantName)) return SqlCeProviderInvariantName.Instance;
            if (type == typeof(DbProviderFactory)) return SqlCeProviderFactory.Instance;
            if (type == typeof(IDbProviderFactoryResolver)) return SqlCeDbProviderFactoryResolver.Instance;
            return SqlCeProviderServices.Instance.GetService(type);
        }

        public IEnumerable<object> GetServices(Type type, object key)
        {
            var service = GetService(type, key);
            if (service != null) yield return service;
        }
    }

    class SqlCeDbConfiguration : DbConfiguration
    {
        public SqlCeDbConfiguration()
        {
            AddDependencyResolver(new SqlCeDbDependencyResolver());
        }
    }

版本: -RhinoCommon 6.30.20288.16410 -.NET 框架 4.8 -EntityFramework 6.4.4 -SqlServerCe.4.0

在 ErikEJ 的指令下,它奏效了!对于那些想要查看代码的人来说,这里是 repo:https://github.com/Tahirhan/RhinoPluginSqlCECodeFirst

谢谢!

【问题讨论】:

标签: c# entity-framework ef-code-first sql-server-ce rhino3d


【解决方案1】:

试试这个(更简单的)方法,我可以使用控制台应用程序:

public class SqlCeDbConfiguration : DbConfiguration 
{
    public SqlCeDbConfiguration()
    {
        SetProviderServices(
            SqlCeProviderServices.ProviderInvariantName,
            SqlCeProviderServices.Instance);

        SetDefaultConnectionFactory(
            new SqlCeConnectionFactory(SqlCeProviderServices.ProviderInvariantName));
    }
}

然后:

[DbConfigurationType(typeof(SqlCeDbConfiguration))]
public class ModelSqlCECodeFirst : DbContext

【讨论】:

  • 非常感谢!我将编辑问题并更新存储库。使用“数据源=|DataDirectory|MyDatabase.sdf;Persist Security Info=False;”产生身份验证错误(因为程序文件中的 rhino ..)我做了一个额外的改变,比如“Data Source=|DataDirectory|” + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\MyDatabase.sdf;Persist Security Info=False;"它奏效了。
  • 据我了解,我需要为 CE 安装运行时才能在客户端的电脑上运行这个项目,我认为我不需要任何外部安装 CE。
  • 如果你使用标准包,你会这样做。但是,如果您能弄清楚如何在代码中注册 DBProviderFactory,您也许可以使用我的 .PrivateDeployment 包。
【解决方案2】:

正如this answer 建议的那样,对于 SQLite 场景,试试这个 DbConfiguration 并且不要忘记删除“|DataDirectory|”连接字符串的一部分

public class SQLiteConfiguration : DbConfiguration
{
    public SQLiteConfiguration()
    {
        SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
        SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance);
        SetProviderServices("System.Data.SQLite", (DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices)));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 2011-10-20
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多