我有一些代码可以在循环内更改数据库中某些数据的值。我只是想知道最先过滤数据的最有效方法是什么?我举个例子: -
上课: -
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;
}
或者没有区别?
答案 0 :(得分:2)
不确定如何编译上面的代码示例。
在myObj
对象中,received
属性为int
,但您正在根据bool
对其进行评估,这会导致此行o.received != true
导致错误Cannot apply operator '!=' to operands of type 'int' and 'bool'
。
检查SQL
代码编译后,使用SQL Profiler查看生成的SQL。
这将显示构造的SQL
<强>基准强>
以下是对 一种可能的 方式的粗略描述,您可以对代码执行进行基准测试。
将代码包装到方法中,例如:
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....
}
答案 1 :(得分:0)
如果您在两个查询之间进行选择,我同意它们都会执行相似的操作,并且基准测试是一个合适的响应。但是,您可以执行一些优化操作。例如,您可以使用方法&#39; AsEnumerable&#39;使用IEnumerable&#39; Where&#39;强制评估。 LINQ&#39; Where&#39;子句(转换为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。这实际上取决于你可以吸收性能成本的地方。