Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 加载实体实例的时间超过1秒_C#_Performance_Entity Framework - Fatal编程技术网

C# 加载实体实例的时间超过1秒

C# 加载实体实例的时间超过1秒,c#,performance,entity-framework,C#,Performance,Entity Framework,我在EF遇到了一件有趣的事情。若我们使用基本实体获取子实体,那个么加载实体需要更多的时间。我的模型如下所示: public abstract class BaseDocument { public Guid Id { get; set; } public string Name { get; set; } } public abstract class ComplexDocument : BaseDocument { public string AuthorName {

我在EF遇到了一件有趣的事情。若我们使用基本实体获取子实体,那个么加载实体需要更多的时间。我的模型如下所示:

public abstract class BaseDocument
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public abstract class ComplexDocument : BaseDocument
{
    public string AuthorName { get; set; }
}

public abstract class SimpleDocument : BaseDocument
{
    public int Level { get; set; }
}

public abstract class OfficeDocument : ComplexDocument
{
    public string OfficeName { get; set; }
}

public abstract class ClassDocument : SimpleDocument
{
    public string HeadName { get; set; }
}

public class WordDocument : OfficeDocument
{
    public int PagesCount { get; set; }
}

public class ExcelDocument : OfficeDocument
{
    public int SheetsCount { get; set; }
}

public class TextDocument : ClassDocument
{
    public int LinesCount { get; set; }
}
我正在使用TPT方法。这是继承树 这是我的上下文类:

public class Context : DbContext
{
    public Context() : base(@"Server=(localdb)\MSSQLLocalDB;Database=EFSIX;Trusted_Connection=True;")
    {
        Database.CreateIfNotExists();
    }
    public DbSet<BaseDocument> BaseDocuments { get; set; }
    public DbSet<ComplexDocument> ComplexDocuments { get; set; }
    public DbSet<SimpleDocument> SimpleDocuments { get; set; }
    public DbSet<OfficeDocument> OfficeDocuments { get; set; }
    public DbSet<ClassDocument> ClassDocuments { get; set; }
    public DbSet<ExcelDocument> ExcelDocuments { get; set; }
    public DbSet<WordDocument> WordDocuments { get; set; }
    public DbSet<TextDocument> TextDocuments { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       modelBuilder.Entity<BaseDocument>().ToTable("BaseDocuments");
       modelBuilder.Entity<ComplexDocument>().ToTable("ComplexDocuments");
       modelBuilder.Entity<SimpleDocument>().ToTable("SimpleDocuments");
       modelBuilder.Entity<OfficeDocument>().ToTable("OfficeDocuments");
       modelBuilder.Entity<ExcelDocument>().ToTable("ExcelDocuments");
       modelBuilder.Entity<WordDocument>().ToTable("WordDocuments");
       modelBuilder.Entity<ClassDocument>().ToTable("ClassDocuments");
       modelBuilder.Entity<TextDocument>().ToTable("TextDocuments");
    }
    public IQueryable<T> GetEntities<T>() where T : class
    {
        return Set<T>();
    }
}
我分别测试了几次moth方法,平均方法
ReadWordDoc
需要25毫秒,方法
ReadBaseDoc
需要52毫秒(实例相同)。 现在这不是什么大问题,但是当我们有复杂的继承时,它需要1秒以上的时间。我创建了10个类并从
BaseDocument
继承。之后,我执行了
ReadBaseDoc
ReadWordDoc
方法
ReadWordDoc
耗时25毫秒,
ReadBaseDoc
耗时1023毫秒。实例是相同的,为什么
ReadBaseDoc
需要更多的时间?在EF中避免此类问题的更好方法是什么

看一看。有很多方法可以使EF更快,但在那些复杂的场景中,ORM只会产生比它解决的问题更多的问题

在您的情况下,一种方法是尝试将继承更改为TablePerType,可能会快一点

另一种方法是找到缓慢的请求,并对它们使用简洁的方式——这样会快得多

最后一种方法是创建一个带有实时缓存的存储库,将整个数据库加载到内存中并保持最新-这应该是应用程序中的单例。如果有多个应用程序使用同一数据库,则需要连接数据更改触发器

一般来说,对于像您这样缓慢(且相对简单)的查询,请使用Dapper+AutoMapper。保持EF,以便数据库与类保持同步,但不要依赖它进行查询


如果你真的想坚持使用ORM,我认为你需要切换nHibernate。我自己还没有尝试过,但从我所读到的来看,它几乎在所有可能的方面都优于它,包括性能和启动时间。

afaik,EF中的主要性能问题与连接建立、模型创建、查询计算和物化有关,其中,前两个将在特定上下文类的第一次调用时发生,第三个将在具有特定条件的每个第一(子)查询时发生,第四个将在每次调用时发生。因此会有一个开销,但一旦你做了第一次查询,它就不应该是非常重要的。关于这些问题,还有很多要提及,但可以归结为这四点。你能添加什么确切的
GetEntities
,并包括模型吗。有多少记录正在尝试fetch@Eldho,我添加了一些细节,将测试放在一个循环中,并重复1000次。这应该显示延迟是否是第一次启动时的开销。TPT或TPH使用的是哪种类型的继承。请包括这些信息和详细信息,以复制该问题。
static void CreateTestData()
    {
        using (Context context = new Context())
        {
            for (int i = 0; i < 20; i++)
            {
                ExcelDocument excel = new ExcelDocument()
                {
                    Id = Guid.NewGuid(),
                    AuthorName = $"ExcelAuthor{i}",
                    Name = $"Excel{i}",
                    OfficeName = $"ExcelOffice{i}",
                    SheetsCount = (i + 1) * 10
                };
                context.ExcelDocuments.Add(excel);

                WordDocument word = new WordDocument()
                {
                    Id = Guid.NewGuid(),
                    AuthorName = $"WordAuthor{i}",
                    Name = $"Word{i}",
                    OfficeName = $"WordOffice{i}",
                    PagesCount = (i + 2) * 10
                };
                context.WordDocuments.Add(word);

                TextDocument text = new TextDocument()
                {
                    Id = Guid.NewGuid(),
                    Name = $"Text{i}",
                    LinesCount = (i + 3) * 10,
                    HeadName = $"Head{i}",
                    Level = i + 5
                };
                context.TextDocuments.Add(text);
            }
            context.SaveChanges();
        }
    }
 static long ReadBaseDoc()
    {
        using (Context context = new Context())
        {
            var words= context.GetEntities<BaseDocument>().Where(e => e.Name.StartsWith("Word"));
            Stopwatch stopwatch = Stopwatch.StartNew();
            var instacnes = excel.ToList();
            stopwatch.Stop();
            return stopwatch.ElapsedMilliseconds;
        }
    }
    static long ReadWordDoc()
    {
        using (Context context = new Context())
        {
            var words = context.GetEntities<WordDocument>().Where(e => e.Name.StartsWith("Word"));
            Stopwatch stopwatch = Stopwatch.StartNew();
            var instacnes = words.ToList();
            stopwatch.Stop();
            return stopwatch.ElapsedMilliseconds;
        }
    }