在Android上,Microsoft.EntityFrameworkCore是否会变慢?

时间:2017-10-10 16:12:18

标签: c# android sqlite xamarin.android entity-framework-core

我正在使用带有Xamarin.Android的Microsoft.EntityFrameworkCore 2.0,我必须向SQLite数据库添加超过400000个项目,但我发现这样做的过程非常缓慢。例如,仅添加1024个项目需要3到4秒。

我遇到的问题是我不知道我做错了什么,或者有更好的方法来完成这项任务(任何优化建议都会受到欢迎)。这次是我们在这种情况下可以完成的最佳性能吗?

我的想法是按批次1024处理/插入400000个项目但是有了这个性能并做了一些保守的数学计算,处理所有项目需要20多分钟,而这次是不可接受的。我一直在努力尝试不同的批次,但表现并没有提高。

为了看看发生了什么,我创建了一些简单的基准代码,这是我的方法:

这是我正在使用的实体:

    public sealed class BenchmarkEntityPoint
    {
        public BenchmarkEntityPoint()
        {
        }

        public BenchmarkEntityPoint(long field1, double field2, double field3, double field4, double field5, double field6, double field7, double field8)
        {
            Field1 = field1;
            Field2 = field2;
            Field3 = field3;
            Field4 = field4;
            Field5 = field5;
            Field6 = field6;
            Field7 = field7;
            Field8 = field8;
        }

        public int Id { get; set; }

        public long Field1 { get; set; }

        public double Field2 { get; internal set; }

        public double Field3 { get; internal set; }

        public double Field4 { get; internal set; }

        public double Field5 { get; internal set; }

        public double Field6 { get; internal set; }

        public double Field7 { get; internal set; }

        public double Field8 { get; internal set; }
    }

这是我的DbContext:

    public sealed class BenchmarkContext : DbContext
    {
        private readonly string path;

        public BenchmarkContext(string path)
        {
            this.path = path;
            ChangeTracker.AutoDetectChangesEnabled = false;
        }

        public DbSet<BenchmarkEntityPoint> BenchmarkEntityPoints { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<BenchmarkEntityPoint>().HasIndex(arg => arg.Field1);
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite($"Filename={path}");
        }
    }

...在某些活动中,我有以下测试方法

        private void OnBenchmarkStart(object sender, System.EventArgs e)
        {
            var benchmarkPath = Path.Combine(global::Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, "EFCBENCHMARKS", "benchmark1");
            var context = // create the context

            var points = // generate 1024 points to test

            var mark = DateTimeOffset.Now;

            context.BenchmarkEntityPoints.AddRange(points);
            context.SaveChanges();

            var elapsed = (DateTimeOffset.Now - mark).TotalMilliseconds;
            // always getting between 3 and 4 sencods
        }

0 个答案:

没有答案