如何使用InteractiveViews(Entity Framework 6.2)?

时间:2018-01-15 12:03:33

标签: c# entity-framework

我尝试使用 InteractiveViews nuget包来改善我的代码第一个应用程序的首次查询执行。

namespace POC.UnitTests
    {
        [TestFixture]
        public class EntityFrameworkViewCachingTests
        {
        private Stopwatch _watch;
        private FileViewCacheFactory _veiwFactory;
        private static string _path;

        [OneTimeSetUp]
        public void Setup()
        {
            _watch = new Stopwatch();
            _connectionDictionary = new Dictionary<int, SqlConnectionStringBuilder>()
            {
                { 1, new SqlConnectionStringBuilder()
                    {
                        UserID = "UserId",
                        Password = "Password",
                        InitialCatalog = "MyDatabase",
                        DataSource = @"MyDb",
                        ConnectTimeout = 30,
                        MinPoolSize = 0,
                        MaxPoolSize = 100,
                        MultipleActiveResultSets = true,
                    }
            };

            _path = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\", "EFCache.xml"));
            _veiwFactory = new FileViewCacheFactory(_path);

            _watch.Start();

            Start(() =>
            {
                using (var ctx = new ThickDbContext(_connectionDictionary[1].ToString()))
                {
                    InteractiveViews.SetViewCacheFactory(
                        ctx,
                        _veiwFactory
                    );
                }

                Debug.WriteLine($"Work with cache consumed: {_watch.ElapsedMilliseconds} ms.");
            });

            _watch.Stop();
        }

        [Test]
        [TestCase(1)]
        public void QueryExecutionPerfomanceTest(int id)
        {
            // Arrange.
            var sqlConnection = _connectionDictionary[id].ToString();

            // Act.
            _watch.Reset();
            _watch.Start();

            //Create dbContext, work with them and dispose it.
            using (var dbContext = new ThickDbContext(sqlConnection))
            {
                var result = dbContext.RESOURCES.SingleOrDefault(r => r.RESOURCEID == id);

                _watch.Stop();

                //Fill dynamic DTO.
                _info = new QueryDataDTO
                {
                    Id = id,
                    DurationTime = _watch.ElapsedMilliseconds,
                    Source = typeof(RESOURCE).Name,
                };

                // Assert.
                Debug.WriteLine($"id: {_info.id}. Duration: {_info.DurationTime} ms.");
            }
        }

        private void Start(Action a)
        {
            // Sync.
            a.Invoke();
        }
    }
}

我一直期望在第一次查询执行时,预生成视图会大大提高性能,但在生成EFCache.xml之前和之后,我总体上会得到相等的结果

另外我读了一篇文章(https://github.com/moozzyk/EFInteractiveViews/issues/7),但实际上并不理解:实际上InteractiveViews可以与EF 6.2一起使用)

两个结果(在视图生成之前和之后)显示:

Work with cache consumed: 7518 ms.
id: 1. Duration: 3007 ms.

因此,总时间:10.525

Work with cache consumed: 7363 ms.
id: 1. Duration: 1968 ms."

因此,总时间:9.331

问:差异可以忽略不计(~13%)我的实施错误在哪里?

P.S我使用非常大的dbContext来获得更明显的结果(482个实体)。

1 个答案:

答案 0 :(得分:0)

所以,我查看了InteractiveViews nuget包源代码,并得出结论认为它在旧的Entity Framework版本上有效,但现在却没有。 (EF 6.2) WorkFlow是构建的,因此它在开始时调用 SetViewCacheFactory 方法来注册自己。

在该方法((IObjectContextAdapter)context).ObjectContext中,如果你有“厚”模型,那么初始化速度非常慢(在我的情况下为482个实体 - 等于 8秒)。
最糟糕的是,这种方法在每次首次执行 时完成,此时缓存文件已经完成或不存在。 P.s我认为有必要检查当前数据库状态。 (

var storageMappingItemCollection = 
                (StorageMappingItemCollection)context.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);)

第二部分(它是关于加载/编写视图缓存xml文件)适用于后续查询,实际上没有更好的内置缓存机制)。因为后续查询在两种情况下都非常快。 当我注意到InteractiveViews包时,我认为在创建缓存文件后,它帮助我 改进了我的第一个查询执行

我想我会 跳过 慢的默认初始化进程,而不是从缓存文件中读取所有适当的信息,但它以其他方式工作(因为我如上所述)

P.s 如果我错了请纠正我