如果value为null,如何返回字符串空

时间:2018-04-04 17:35:30

标签: c# entity-framework-6

我想在SomethingName为空时返回一个空字符串。 plants.Something.Name != null ? plants.Something.Name : string.Empty仍然得到一个空指针。我调试了我的应用程序,知道这导致了NullPointerException。

当我在数据库中为SomethingName设置数据时,我没有得到空指针异常。

有没有更好的方法来解决这个问题?

    public FlowerMetaData GetLeafByFlowerId(int flowerId, string flowerName)
    {
        _flowerContext = _contextUtility.GetFlowerContext(flowerName);

        var flowerData = (from flowers in _flowerContext.Flowers
                            where flowers.FlowerId == flowerId
                            join plants in _flowerContext.Plants on flowers.PlantId equals plants.PlantId
                            join leafs in _flowerContext.Leafs on flowers.LeafAk equals leafs.LeafAK
                            select new FlowerMetaData
                            {
                                PlantId = plants.PlantId,
                                PlantName = plants.PlantName,
                                FlowerName = FlowerName.ToUpper(),
                                FlowerNumber = leafs.FlowerNumber,
                                SomethingName = plants.Something.Name != null ? plants.Something.Name : string.Empty,
                                CreatedId = plants.CreatedId,
                            }).FirstOrDefault();

        return flowerData;
    }

StackTrace

    "Message": "An error has occurred.",
    "ExceptionMessage": "No flower found with id = 37.",
    "ExceptionType": "System.NullReferenceException",
    "StackTrace": "   at Flower.Services.FlowerService.GetLeafByFlowerId(Int32 flowerId, String flowerName)
at Flower.Controllers.Controllers.FlowerController.GetFlower(Int32 id, String client)\r\n   at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
  at Sentinel.Services.AuthFilters.AddChallengeOnUnauthorizedResult.<ExecuteAsync>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.AuthenticationFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}

2 个答案:

答案 0 :(得分:3)

通常你可以使用C#6中的null-conditional operator,结合C#2中的空合并运算符来实现这一点:

SomethingName = plants.Something?.Name ?? ""

如果plants.Something?.Name求值为null,则表达式plants.Something将计算为null(而不是抛出异常)。然后?? ""部分只是说“如果表达式的结果为null,请改用空字符串。”

如果plants本身可以为null,则可以使用:

SomethingName = plants?.Something?.Name ?? ""

...但在这种情况下你不需要。

但是,有一个问题:如果你在LINQ提供程序中使用IQueryable<T>(而不是IEnumerable<T>作为对象的LINQ通常会这样做),那么查询表达式的每个部分都将是转换为表达式树,表达式树不支持空条件运算符。因此,您可能需要在查询中执行投影,然后在进程中执行最后一部分。例如:

var entry = (from flowers in _flowerContext.Flowers
             where flowers.FlowerId == flowerId
             join plants in _flowerContext.Plants on flowers.PlantId equals plants.PlantId
             join leafs in _flowerContext.Leafs on flowers.LeafAk equals leafs.LeafAK
             select new { plants, leafs }).FirstOrDefault();
return entry == null 
    ? null // No entry in the database
    : new FlowerMetaData
      {
          PlantId = entry.plants.PlantId,
          PlantName = entry.plants.PlantName,
          FlowerName = FlowerName.ToUpper(),
          FlowerNumber = entry.leafs.FlowerNumber,
          SomethingName = entry.plants.Something?.Name ?? "",
          CreatedId = entry.plants.CreatedId,
       };

答案 1 :(得分:1)

未经测试但

SomethingName = plants.Something?.Name ?? string.empty

应该做所需要的。黛西说什么!