1

我正在开发一个小应用程序来在 SharePoint 中运行一些计时器作业。我不只是使用 aforeach来遍历所有作业并选择我想要的作业,而是尝试通过 Linq 语句通过 Guid 选择它们。但是,我运气不佳。这是我到目前为止所拥有的:

   foreach (SPService service in centralAdmin.Farm.Services)
{
   var traceJob =
       from jobDefinition in service.JobDefinitions
       where jobDefinition.Id == traceGuid
       select jobDefinition;

   SPJobDefinition jobInfo = traceJob as SPJobDefinition
   Console.WriteLine(jobInfo.DisplayName);
 }

编辑我收到的错误是“NullReferenceException”Console.WriteLine(jobInfo.DisplayName)

我确信我错过了一些东西,因为这是我第一次使用 LINQ 语句,但我无法弄清楚我做错了什么。我将 traceJob 转换为因为SPJobDefinition否则我无法访问. 任何提示或指示将不胜感激!SPJobDefinitiontraceJob

编辑 枚举在搜索 Guid 时不会产生任何结果。但是,如果我执行以下代码:

    foreach (SPJobDefinition jobDefinition in service.JobDefinitions)
    {
     if (jobDefinition.Id == traceGuid)
     {
       jobDefinition.RunNow();
       Console.WriteLine(jobDefinition.DisplayName);
     }
    }

它将完全恢复我期望看到的内容——作业定义的显示名称。这似乎表明问题不在于有缺陷的 Guid 或不存在的作业。

4

2 回答 2

1

LINQ 返回一个结果枚举器,无论您的查询总是最多返回一个项目。而且由于 LINQ 返回枚举器而不是实际结果,因此您必须对其进行迭代。通过调用ToList()FirstOrDefault()或任何类似的方式。

试试这个语句:

SPJobDefinition jobInfo = traceJob.SingleOrDefault() ?? new SPJobDefinition();

由于您的结果对象已经是正确的类型,因此不需要强制转换。我还使用了空合并运算符以防您的 LINQ 语句不返回任何内容(作业信息不存在)。在这种情况下SingleOrDefault()将返回null,因为这是引用类型的默认值。

您当然可以省略空合并操作并null在使用前检查jobInfo

于 2012-11-21T16:12:09.643 回答
1

你得到的异常是因为你的as操作总是会失败,当as失败时它不会抛出异常,它只是返回 null。异常来自使用该空值。

traceJob根本不需要演员。使用var并不意味着它实际上是变量类型,甚至根本不知道。它只是意味着编译器将查看右边的表达式=并使用它(静态地,在编译时)来确定该变量的类型。在这种情况下,将鼠标悬停var会显示它实际上是一个IEnumerable<SPJobDefinition>. 您拥有的是一系列工作定义,而不仅仅是一个。First您可以通过、FirstOrDefaultSingle或轻松获取序列中的第一项SingleOrDefault。这样做之后,您将只有一个项目,并且您根本不需要投射它。

var traceJob =
    (from jobDefinition in service.JobDefinitions
    where jobDefinition.Id == traceGuid
    select jobDefinition)
    .SingleOrDefault();

if(traceJob != null)
    Console.WriteLine(traceJob.DisplayName);
于 2012-11-21T16:23:50.493 回答