[英]Entity Framework Fluent, Table-Per-Type performance alternatives
我目前正在研究EF Fluent项目(是的,我确实喜欢这样写),该项目采用EF 4.3上的Table-Per-Type体系结构采用模型优先的方法。
正如我在过去几个月中发现的那样,Table-Per-Type和继承只是不能很好地发挥作用-> 更多信息 。 我使用的是带有七个派生类的单个基类,而返回七个派生类中的项目并不是特别快。 在执行时间方面,要检索5条记录的清单EF花费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;
但是,这不适用于InvalidOperationException,因为它抱怨CommandText无效,并且我必须提供'ContainerName'。 我的猜测是,如果我使用的是EDMX文件,则可以设置此设置项(并且使用DefaultContainerName不起作用)。 但是我使用的是流利的方法,我觉得自己已经走到了尽头。
所以...
有哪些方法可以解决EF和每类型表的性能问题? 是否可以使用Fluent / Model First方法通过ObjectContext执行存储过程? 我可以执行标准的SQLClient.SqlDataReader并将其转换为ObjectContext吗?
提前致谢...
OK-看来ObjectContext可以从System.Data.SqlClient.SqlDataReader转换,这意味着我不需要(直接)从dbContext派生。 这是示例代码...
IList<MyBaseClass> items = new List<MyBaseClass>();
ObjectContext oContext = ((IObjectContextAdapter)dbContext).ObjectContext;
using (var sqlConn = new SqlConnection(dbContext.Database.Connection.ConnectionString))
{
SqlCommand sqlComm = new SqlCommand(){
Connection = sqlConn,
CommandText = "spGetMyDerivedItems",
CommandType = CommandType.StoredProcedure
};
sqlConn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
oContext.Translate<MyFirstDerivedClass>(reader).ToList().ForEach( x => items.Add(x));
reader.NextResult();
...repeat for each derived type...
}
}
return items;
显然,最好的答案是EF会采取这一措施,但我暂时对以上情况感到满意。 迁移到EF5听起来是个不错的选择-但在各种时间范围内,您所知道的魔鬼更好:)
谢谢您的帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.