Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有点像VLOOKUP_C#_Performance - Fatal编程技术网

C# 有点像VLOOKUP

C# 有点像VLOOKUP,c#,performance,C#,Performance,我试图合并两个不同对象的列表,其中一个特定字段(employeeID)等于另一个列表中的一个特定字段[0,0]。我的代码如下所示: int i = Users.Count() - 1; int i2 = oracleQuery.Count() - 1; for (int c = 0; c <= i; c++) { for (int d = 0; d <= i2; d++) { if (Users[c].getEmployeeID().ToString(

我试图合并两个不同对象的列表,其中一个特定字段(employeeID)等于另一个列表中的一个特定字段[0,0]。我的代码如下所示:

int i = Users.Count() - 1;
int i2 = oracleQuery.Count() - 1;
for (int c = 0; c <= i; c++)
{
    for (int d = 0; d <= i2; d++)
    {
        if (Users[c].getEmployeeID().ToString() == oracleQuery[d][0,0].ToString())
        {
            Users[c].setIDMStatus(oracleQuery[d][0,1].ToString());
        }
    }
}
inti=Users.Count()-1;
int i2=oracleQuery.Count()-1;
对于(int c=0;c,可以使用连接:


请注意,如果
getEmployeeId()
和oracleQuery的
[0,0]
元素属于同一类型,则可以消除
ToString()
调用。如果数据来自数据库,则可以在那里进行联接。否则,可以对两个列表进行排序,并进行合并联接,这将比现在更快


然而,自从C#引入LINQ以来,在代码中有很多方法可以做到这一点。只需查找使用LINQ加入/合并列表即可。

就效率而言,我注意到的唯一一件事是使用Enumerable.Count()方法,该方法在for循环中再次显式循环之前枚举结果。我认为LINQ实现将摆脱通过结果来计算元素的过程

我不知道您对使用Linq查询表达式的感觉如何,但这是我最喜欢的:

    var matched = from user in Users
                  join item in oracleQuery on user.getEmployeeID().ToString() equals item[0,0].ToString()
                  select new {user = user, IDMStatus = item[0,1] };

    foreach (var pair in matched) {
        pair.user.setIDMStatus(pair.IDMStatus);
    }
您还可以使用嵌套的foreach循环(如果存在多个匹配项,并且多次调用set):

或者如果只有一个匹配是肯定的:

    foreach (var user in Users) {
        var match = oracleQuery.SingleOrDefault(item => user.getEmployeeID().ToString() == item[0,0].ToString()) 
        if (match != null) {
            user.setIDMStatus(match[0,1]);
        }
    }

我认为您编写的代码中没有任何真正的效率问题,但您可以将其与LINQ中的实现进行基准测试。我认为使用
foreach
LINQ查询表达式可能会使代码更易于阅读,但我认为效率没有问题。您还可以编写LINQ查询表达式关于使用Linq方法语法,正如在另一个答案中所做的那样。

您的数据源是什么?Oracle RDBMS?p.s您正在寻找一个内部联接,它将构成db查询的一部分。我的数据源是Oracle db和Active Directory中的数据。感谢您提供的额外方法,Steve。我本来会做一个foreach语句,但出于某种原因(很可能是用户错误),它不想这样做。关于枚举的一些事情……尽管有一个奇怪的问题——查询中的select子句不会生成新对象而不是更改现有对象吗?(只是好奇。我真的不知道。)这将创建一个新的匿名对象,该对象包含对现有对象的引用(除非它们是值类型,在这种情况下,它们将被复制)。编译器可能会优化对象创建,但可能不会。最大的节省是在代码中循环两次…对Count()扩展方法的调用将枚举结果。然后,显式循环。使用Linq语法(my和Copsey的实现是相同的,只是我使用查询语法,Copsey使用方法语法),只有一个枚举。
    foreach (var user in Users) {
        foreach (var match in oracleQuery.Where(item => user.getEmployeeID().ToString() == item[0,0].ToString()) {
            user.setIDMStatus(match[0,1]);
        }
    }
    foreach (var user in Users) {
        var match = oracleQuery.SingleOrDefault(item => user.getEmployeeID().ToString() == item[0,0].ToString()) 
        if (match != null) {
            user.setIDMStatus(match[0,1]);
        }
    }