简体   繁体   English

覆盖DbContext EF6

[英]Override DbContext EF6

I'm trying to understand how to dynamically create the connection string for my DbContext, but my application says it has no connection string in the app.config (and that's correct because I don't want to use it in the app.config or web.config). 我试图了解如何为我的DbContext动态创建连接字符串,但我的应用程序说它在app.config中没有连接字符串(这是正确的,因为我不想在app.config中使用它或web.config中)。 This is what I have: 这就是我所拥有的:

In my solution I have a project called InterfaceApp. 在我的解决方案中,我有一个名为InterfaceApp的项目。 It is a ASP.NET MVC 5 application. 它是一个ASP.NET MVC 5应用程序。 When I put my connection string in the web.config all seems to be working fine. 当我把我的连接字符串放在web.config中似乎一切正常。

In my solution I have an other project called InterfaceApp.Connector.Erp1. 在我的解决方案中,我有一个名为InterfaceApp.Connector.Erp1的项目。 Here I want to connect to an ERP application and fetch some items. 在这里,我想连接到ERP应用程序并获取一些项目。 So in my repository I have: 所以在我的存储库中我有:

namespace InterfaceApp.Connector.Erp1.Repository
{
    internal class ItemRepository : IItemRepository
    {
        public IEnumerable<Item> Items
        {
            get
            {
                List<Item> items = new List<Item>();

                using (Models.Entities context = new Models.Entities())
                {
                     var itemList = context.Items.ToList();
                    foreach(var item in itemList)
                    {
                        items.Add(new Item() { Id = item.ID, Description = item.Description, ItemCode = item.ItemCode });
                    }
                }

                return items.ToList();
            }
        }
    }
}

I've created a partial class to connect to the database: 我创建了一个连接数据库的部分类:

namespace InterfaceApp.Connector.Erp1.Models
{
    public partial class Entities
    {
        public Entities(string connectionString)
            : base(ConnectionString())
        {
        }


        private static string ConnectionString()
        {
            SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder
            {
                DataSource = "MyServer", //When this works it will be dynamic
                InitialCatalog = "XXX", //When this works it will be dynamic
                PersistSecurityInfo = true,
                IntegratedSecurity = true,
                MultipleActiveResultSets = true,

            };

            var entityConnectionStringBuilder = new EntityConnectionStringBuilder
            {
                Provider = "System.Data.SqlClient",
                Metadata = "res://*/Models.Erp1Model.csdl|res://*/Models.Erp1Model.ssdl|res://*/Erp1Model.msl",
                ProviderConnectionString = sqlBuilder.ConnectionString

            };

            return entityConnectionStringBuilder.ConnectionString;

        }
    }
}

The Context class that is auto-generated by EF6 (Db First) looks like this: 由EF6(Db First)自动生成的Context类如下所示:

namespace InterfaceApp.Connector.Erp1.Models
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;

    public partial class Entities : DbContext
    {
        public Entities()
            : base("name=Entities")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }

        public virtual DbSet<Items> Items { get; set; }
    }
}

When I run my application, the debugger stops at the auto-generated class, but not at my partial class. 当我运行我的应用程序时,调试器在自动生成的类中停止,但不在我的部分类中停止。 Because it cannot find the connection string Entities in my app.config and web.config it generates an error saying that the connection string is not found in the application config file. 因为它无法在我的app.config和web.config中找到连接字符串Entities ,所以它会生成错误,指出在应用程序配置文件中找不到连接字符串。 What am I doing wrong? 我究竟做错了什么?

When you are calling the DbContext, you're calling the empty constructor ( new Models.Entities() ). 当您调用DbContext时,您正在调用空构造函数( new Models.Entities() )。 Thus, it will call the auto-generated DbContext. 因此,它将调用自动生成的DbContext。 If you want to call your partial class, you need to call it explicitly with the parameter. 如果要调用部分类,则需要使用参数显式调用它。

Remember when you create a partial class, the compiler merges them, so you have this when compiled : 请记住,当您创建一个分部类时,编译器会将它们合并,因此您在编译时可以使用它:

public partial class Entities : DbContext
{
    public Entities()
        : base("name=Entities")
    {
    }
    public Entities(string connectionString)
        : base(ConnectionString())
    {
    }


    private static string ConnectionString()
    {
        SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder
        {
            DataSource = "MyServer", //When this works it will be dynamic
            InitialCatalog = "XXX", //When this works it will be dynamic
            PersistSecurityInfo = true,
            IntegratedSecurity = true,
            MultipleActiveResultSets = true,

        };

        var entityConnectionStringBuilder = new EntityConnectionStringBuilder
        {
            Provider = "System.Data.SqlClient",
            Metadata = "res://*/Models.Erp1Model.csdl|res://*/Models.Erp1Model.ssdl|res://*/Erp1Model.msl",
            ProviderConnectionString = sqlBuilder.ConnectionString

        };

        return entityConnectionStringBuilder.ConnectionString;

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<Items> Items { get; set; }
}

What you probably need aa method to create your DbContext and call it instead of calling a new DbContext. 您可能需要一种方法来创建DbContext并调用它而不是调用新的DbContext。

public static Entities Create()
{
    return new Entities(ConnectionString());
}

Then you can use it this way : 然后你可以这样使用它:

using (var context = Entities.Create())
{
     //...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM