2012-06-12 40 views
1

我有一些代碼,在循環中改變我的數據庫中的一些數據的值。我只是想知道什麼是首先過濾數據的最有效方式?我舉一個例子: -使用實體框架,哪種方法更高效?

隨着等級: -

public class myObj 
{ 
    int id {get;set;} 
    string product {get; set;} 
    string parent{get;set;} 
    int received {get;set;} 
} 

而且的DbContext: -

public class myCont:DbContext 
{ 
    public DbSet<myObj> myObjs {get;set;} 
} 

是更好地做到這一點: -

int[] list; 
/* Populate list with a bunch of id numbers found in myOBjs */ 
myCont data = new myCont(); 
myObj ob = data.myObjs.Where(o => o.parent == "number1"); 
foreach(int i in list) 
{ 
    ob.First(o => o.id == i && o.received != true).received = true; 
} 

或者: -

int[] list; 
/* Populate list with a bunch of id numbers found in myOBjs */ 
myCont data = new myCont(); 
foreach(int i in list) 
{ 
    data.myObjs.First(o => o.parent == "number1" && o.id == i && o.received != true).received = true; 
} 

還是沒有區別?

+3

嘗試基準測試 –

+0

您可以使用sql配置文件檢查linq生成的命令 – uowzd01

+0

僅當代碼遍歷IQueryable時纔會生成sql查詢。 EF延遲執行,直到需要實現對象。 –

回答

2

不知道如何編譯上面的代碼示例。

在你myObj對象時,received屬性是int,但要針對bool這應該引起此行o.received != true到產生錯誤Cannot apply operator '!=' to operands of type 'int' and 'bool'評測吧。

檢查SQL
一旦代碼編譯使用SQL Profiler看到的是生成了什麼SQL。下面

會告訴你構建SQLS

標杆
是唯一一個可能你可以基準代碼執行方式非常粗略的描述。

包裝你代碼到一個方法,例如:

public void TestingOperationOneWay() 
{ 
    int[] list; 
    /* Populate list with a bunch of id numbers found in myOBjs */ 
    myCont data = new myCont(); 
    myObj ob = data.myObjs.Where(o => o.parent == "number1"); 
    foreach(int i in list) 
    { 
     ob.First(o => o.id == i && o.received != true).received = true; 
    } 
} 

和:

public void TestingOperationAnotherWay() 
{ 
    int[] list; 
    /* Populate list with a bunch of id numbers found in myOBjs */ 
    myCont data = new myCont(); 
    foreach(int i in list) 
    { 
     data.myObjs.First(o => o.parent == "number1" && o.id == i && o.received != true).received = true; 
    } 
} 

板條箱的方法,其在使用所述Stopwatch此類似每種方法的次迭代x量:

private static TimeSpan ExecuteOneWayTest(int iterations) 
{ 
    var stopwatch = Stopwatch.StartNew(); 

    for (var i = 1; i < iterations; i++) 
    { 
     TestingOperationOneWay(); 
    } 

    stopwatch.Stop(); 

    return stopwatch.Elapsed; 
} 

評估結果與此類似:

static void RunTests() 
{ 
    const int iterations = 100000000; 

    var timespanRun1 = ExecuteOneWayTest(iterations); 
    var timespanRun2 = ExecuteAnotherWayTest(iterations); 

    // Evaluate Results.... 
} 
+0

感謝這個,我不知道秒錶的對象。至於代碼編譯沒有好上面的代碼是不是從我的項目,只是有點的示例代碼來演示什麼,我想在我的應用程序做,但感謝這一點。 –

+0

你非常歡迎。我很高興它有幫助。 – Nope

0

在兩個查詢之間進行選擇的情況下,我同意它們都以類似方式執行,並且基準測試是一個適當的響應。但是,有些事情可以做到優化。例如,您可以使用方法'AsEnumerable'來強制使用IEnumerable'Where'子句LINQ'Where'子句(即轉換爲SQL並針對數據源執行或處理對象層次結構中的位置)的差異進行評估。既然你似乎僅僅操作特性(而不是實體關係),你可以這樣做:

int[] list; 
/* Populate list with a bunch of id numbers found in myOBjs */ 
myCont data = new myCont(); 
myObj ob = data.myObjs.Where(o => o.parent == "number1").AsEnumerable<myObj>(); 
foreach(int i in list) 
{ 
    ob.First(o => o.id == i && o.received != true).received = true; 
} 

這樣做會避免碰到數據庫中的每個記錄(可能是避免網絡延遲)的罰款,但會增加你的記憶足跡。這是一個associated LINQ further explaining this idea。這實際上取決於你可以吸收性能成本的地方。