大型EF数据库模型是否会极大地消耗应用程序性能

时间:2016-06-23 09:22:16

标签: c# entity-framework

我们的项目依赖于一个大型MSSQL数据库。该数据库暴露给许多其他应用程序。其中一些使用EF数据库的第一个模型。在该数据库中有超过300个表。其中一些我们需要使用它们中的一些用于app的其他部分。当我们对数据库进行反向工程时,EF会创建一个包含所有表的模型而没有任何问题有时我们的代码只使用一个表,但我们仍然需要声明大型模型。

我的问题是,如果我们总是初始化一个包含大量表格的模型,那么应用程序的性能是否会受到影响。

当我们有这样的代码

时,幕后发生了什么
public string peaceOfData(int id)
{
    using (modelWhit500tables largeMode = new modelWhit500tables())
    {
        return largeMode.onlyOneTable.Find(id).data;
    }
}

我们的应用程序主要是包含许多Web API控制器的MVC应用程序。

我们希望拥有一个大型模型,因为数据库层简单,并且易于维护数据库设计。

2 个答案:

答案 0 :(得分:1)

我无法对EF的内部进行评论,但this post至少在一定程度上回答了您的问题:

  

巨型情境

     

即使您预编译视图,实体框架仍然必须在首次初始化上下文时工作,并且该工作是   与模型中的实体数量成比例。对于一个   少数表格不用担心。

     

但是,使用EF的常用方法是从预先存在的数据库中自动生成上下文,并简单地导入   所有物体。当时这是最谨慎的,因为它最大化你的   能够使用数据库。因为即使是相当适度的数据库   可以包含数百个对象,性能影响很快   失控,启动时间可以在几分钟内完成。它的   值得考虑你的背景是否真的需要了解   整个架构,如果没有,删除这些对象。

需要注意的是,第一次应用程序实例访问数据库上下文时,上下文将经历初始化过程。这就是上面引用的内容。对于应用程序或Web服务,这只会发生一次,即使您的代码处理了上下文。这是您的应用程序的一次性性能打击。您可能希望在应用程序启动时显式触发此操作,而不是惩罚第一个用户访问您的应用程序。

EF的性能注意事项在this MSDN article中有所描述。加载模型和映射元数据最有可能获得的最大打击。在您的情况下,对于MVC和Web API应用程序,它取决于您如何定义应用程序域:

enter image description here

答案 1 :(得分:0)

您可以使用代码优先方法创建自己的dbContext,而不是将生成的模型与所有300个表一起使用。然后,您可以使用数据库的简化表面视图。您甚至可以忽略应用程序不需要的每个表的字段以获得更好的性能。作为仅使用300个表中的2个表的简化示例。

公共类客户     {         public int id {get;设置;}

    public string Custno { get; set; }
    public string Name { get; set; }
    public decimal Balance { get; set; }

    // The table other fields are ignored...

    public List<CustomerAddress> Addresses { get; set; }


    }
}

 public class CustomerAddress 
{
    public int id { get; set;}

    public int Customerid { get; set; }

    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string Cityname { get; set; }
    public string Statename { get; set; }
    public string Countryname { get; set; }
    public string Zipname { get; set; }

    public Customer Customer { get; set; }


}
    public class CustomerMap()
    {

        ToTable("Customers");

        Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        HasKey(k => k.Id);

        Property(p => p.Custno).HasMaxLength(8).IsRequired();
        Property(p => p.Name).HasMaxLength(120).IsRequired();
        Property(p => p.Balance).HasPrecision(18, 2);

        HasMany(a => a.Addresses).WithRequired(x => x.Customer).HasForeignKey(k => k.Customerid);  

    }

     public class CustomerAddressMap()
    {

        ToTable("CustomerAddresses");

        Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        HasKey(k => k.Id);


        Property(p => p.Address1).HasMaxLength(120);
        Property(p => p.Address2).HasMaxLength(120);
        Property(p => p.Cityname).HasMaxLength(40);
        Property(p => p.Countryname).HasMaxLength(40);
        Property(p => p.Statename).HasMaxLength(40);
        Property(p => p.Zipname).HasMaxLength(6);


        HasRequired(x => x.Customer).WithMany(a => a.Addresses).HasForeignKey(k => k.Customerid).WillCascadeOnDelete(false);

    }

    public class YourAppContext : DbContext
{
    public YourAppContext()
        : base("YourAppContext")
    {
        Database.SetInitializer<YourAppContext>(null);     
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new CustomerMap());            
        modelBuilder.Configurations.Add(new CustomerAddressMap());      

    }


    public DbSet<Customer> Customer { get; set; }
    public DbSet<CustomerAddress> CustomerAddresses { get; set; }


}

这样,您可以使用YourAppContext仅查询和更新所需的表和字段。