我目前正在开发一个 EF Fluent 项目(是的,我确实喜欢这样写),该项目在 EF 4.3 上采用模型优先的方法,采用 Table-Per-Type 架构。
正如我在过去几个月中发现的那样,Table-Per-Type 和继承并不能很好地发挥作用 ->更多信息。我正在使用具有七个派生类的单个基类,并且仅在七个派生类中返回项目并不是特别快。在执行时间方面,EF 检索包含 5 条记录的列表需要 5 到 7 秒,随后的执行大约需要 2.5 到 4 秒。可以肯定地说这是不可接受的,所以我正在寻找替代方法......
我能做的是多次访问数据库,即尝试检索每种类型的对象个体并整理成一个集合;但是,该代码充其量是笨拙的,即
IList<MyBaseClass> items = new List<MyBaseClass>();
dbContext.Database.SqlQuery<MyFirstDerivedClass>("SELECT * FROM MyBaseClass INNER JOIN MyFirstDerivedClass ON...").ToList().ForEach(x => items.Add(x));
... repeat for each derived class...
return items;
但它有效!对数据库的第一次点击需要 2 秒,随后的查询只需 200 毫秒。
我的问题是,这不是很优雅,可维护等,等等。我一直在玩弄将 dbContext 转换为 ObjectContext 并使用类似这样的存储过程('spGetMyDerivedItems')运行,返回所有排序的派生结果集一分贝命中...
IList<MyBaseClass> items = new List<MyBaseClass>();
ObjectContext oContext = ((IObjectContextAdapter)dbContext).ObjectContext;
using (var connection = oContext.Connection as EntityConnection)
{
EntityCommand command = connection.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "spGetMyDerivedItems";
connection.Open();
using (EntityDataReader reader = command.ExecuteReader())
{
oContext.Translate<MyFirstDerivedClass>(reader).ToList().ForEach( x => items.Add(x));
reader.NextResult();
...repeat for each derived type...
}
}
return items;
但是,这不适用于抱怨 CommandText 无效并且我必须提供“ContainerName”的 InvalidOperationException。我在这里的猜测是,如果我使用的是 EDMX 文件,我可以设置这个设置项(并且使用 DefaultContainerName 不起作用)。但我正在采取一种流利的方法,我觉得我已经走到了死胡同。
所以...
有哪些方法可以解决 EF 和 table-per-type 的性能问题?是否可以使用 Fluent / Model First 方法通过 ObjectContext 执行存储过程?我可以执行标准 SQLClient.SqlDataReader 并转换为 ObjectContext 吗?
提前致谢...