覆盖DbContext EF6

时间:2016-09-18 16:01:14

标签: c# entity-framework

我正在尝试了解如何为我的DbContext动态创建连接字符串,但我的应用程序说它在app.config中没有连接字符串(这是正确的,因为我不想在应用程序中使用它.config或web.config)。这就是我所拥有的:

在我的解决方案中,我有一个名为InterfaceApp的项目。它是一个ASP.NET MVC 5应用程序。当我把我的连接字符串放在web.config中时,似乎一切正常。

在我的解决方案中,我有一个名为InterfaceApp.Connector.Erp1的项目。在这里,我想连接到ERP应用程序并获取一些项目。所以在我的存储库中我有:

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();
            }
        }
    }
}

我创建了一个连接数据库的部分类:

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;

        }
    }
}

由EF6(Db优先)自动生成的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; }
    }
}

当我运行我的应用程序时,调试器在自动生成的类中停止,但不在我的部分类中停止。因为它在我的app.config和web.config中找不到连接字符串Entities,所以它会生成错误,指出在应用程序配置文件中找不到连接字符串。我做错了什么?

1 个答案:

答案 0 :(得分:0)

当您调用DbContext时,您正在调用空构造函数(new Models.Entities())。因此,它将调用自动生成的DbContext。如果要调用部分类,则需要使用参数显式调用它。

请记住,当您创建一个分部类时,编译器会将它们合并,因此在编译时会有这个:

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; }
}

您可能需要一种方法来创建DbContext并调用它而不是调用新的DbContext。

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

然后你可以这样使用它:

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