簡體   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