我尝试使用 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个实体)。
答案 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 如果我错了请纠正我