我想在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()"
}
答案 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
应该做所需要的。黛西说什么!