繁体   English   中英

实体框架流利的按表类型性能替代

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM