LINQ左连接抛出System.NullReferenceException或System.InvalidCastException

时间:2013-03-11 17:18:20

标签: c# linq

我一直在尝试创建一个LINQ语句,它将使用左外连接连接两个表。

以下代码获取为登录用户工作的人员DataTable(包含Active Directory用户名),获取另一个DataTable,这是AD用户名和应用程序登录名之间的交叉引用,然后加入它们以创建一个List<string>,其中包含应用程序登录名(如果存在),否则包含AD用户名,适用于为登录用户工作的每个人。

当登录列表中不包含下属列表中的任何人时,会发生NullReferenceException错误(在select new行上)。

当登录列表确实包含某个位于下属列表中的人时,会发生InvalidCastException错误(在return result...行上)。这里的完整错误是:

  

System.InvalidCastException:无法转换类型的对象   '&lt;&gt; f__AnonymousType1`1 [System.String]'输入'System.String'

TMReportsDataSet.EmployeeDataTable subordinates = SessionTyped.Subordinates;
TMReportsDataSet.EmployeeLoginDataTable logins = CacheTyped.Logins;

var result = from t1 in subordinates.AsEnumerable()
             join t2 in logins.AsEnumerable()
             on t1.ADAccountName equals t2.ADAccountName
             into joinedDT
             from t2 in joinedDT.DefaultIfEmpty()
             select new
             {
                 userName = (string)(t2.LoginName ?? t1.ADAccountName)
             };

return result.Cast<string>().ToList<string>();

2 个答案:

答案 0 :(得分:3)

您正在尝试将匿名类型转换为字符串。删除匿名类型的使用,如下所示:

var result = from t1 in subordinates.AsEnumerable()
                 join t2 in logins.AsEnumerable()
                 on t1.ADAccountName equals t2.ADAccountName
                 into joinedDT
                 from t2 in joinedDT.DefaultIfEmpty()
                 select (string)(t2.LoginName ?? t1.ADAccountName);

return result.ToList();

答案 1 :(得分:2)

由于我对马格努斯的回答被拒绝了[我不明白为什么?]这里是我的问题的完整答案,这基本上是马格努斯给出的答案,但另外检查是否t2 == null避免出现NullReferenceException错误。

var result = from t1 in subordinates.AsEnumerable()
                 join t2 in logins.AsEnumerable()
                 on t1.ADAccountName equals t2.ADAccountName
                 into joinedDT
                 from t2 in joinedDT.DefaultIfEmpty()
                 select (string)(t2 == null ? "" : (t2.LoginName ?? t1.ADAccountName));

return result.ToList();