在我们的C#代码中,我最近更改了linq-to-sql select new查询中的一行,如下所示:
OrderDate = (p.OrderDate.HasValue ?
p.OrderDate.Value.Year.ToString() + "-" +
p.OrderDate.Value.Month.ToString() + "-" +
p.OrderDate.Value.Day.ToString() : "")至:
OrderDate = (p.OrderDate.HasValue ?
p.OrderDate.Value.ToString("yyyy-mm-dd") : "")这一变化使这条线变得更小更整洁。在我们的开发环境中,它也可以与我们的SQL2008数据库很好地协同工作。但是,当代码部署到使用SQL2005的生产环境中时,我收到了一个异常,声明为:Nullable Type must have a value。为了进一步分析,我将(p.OrderDate.HasValue ? p.OrderDate.Value.ToString("yyyy-mm-dd") : "")复制到一个字符串中(在Linq语句之外),没有任何问题,所以它只会在我的Linq内部引起一个问题。这个问题只是与SQL 2005使用不同的日期格式而不是SQL 2008有关吗?
以下是Linq的更多信息:
var FilteredOrders = [linq-to-sql query].AsEnumerable().ToList<Order>();
dt = FilteredOrders.Where(x => x != null).Select(p =>
new
{
Order = p.OrderId,
link = "/order/" + p.OrderId.ToString(),
StudentId = (p.PersonId.HasValue ? p.PersonId.Value : 0),
FirstName = p.IdentifierAccount.Person.FirstName,
LastName = p.IdentifierAccount.Person.LastName,
DeliverBy = p.DeliverBy,
OrderDate = p.OrderDate.HasValue ?
p.OrderDate.Value.Date.ToString("yyyy-mm-dd") :
""
}).ToDataTable();这是从Order对象列表中进行选择。FilteredOrders列表来自另一个linq- to -sql查询,在将它提供给这个特定的select new查询之前,我对它调用了.AsEnumerable。
在常规代码中这样做效果很好:
if (o.OrderDate.HasValue)
tempString += " " + o.OrderDate.Value.Date.ToString("yyyy-mm-dd");下面是错误的堆栈跟踪。这是一所学校的一个大型系统的一部分,用于从DB检索订单以显示在屏幕上。
Line 46:
Line 47: dt = FilteredOrders.Where(x => x != null).Select(p =>
Line 48: new
Line 49: {
Line 50: Order = p.OrderId,
Stack Trace:
[InvalidOperationException: Nullable object must have a value.] System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +51 System.Nullable`1.get_Value() +1373881 Aqueduct.Platform.Web.packages.finance_carttranscriptorder_default.<PopulateSearchResultsGrid>b__1(CartTranscriptOrder p) in D:\Repositories\aqueduct\Aqueduct.Platform.Web\trunk\packages\finance\carttranscriptorder\default.aspx.cs:48 System.Linq.WhereSelectListIterator`2.MoveNext()
+107 System.Linq.Buffer`1..ctor(IEnumerable`1 source) +434 System.Linq.<GetEnumerator>d__0.MoveNext()
+108 Aqueduct.Core.Data.ObjectShredder`1.Shred(IEnumerable`1 source, DataTable table, Nullable`1 options) in D:\Repositories\aqueduct\Aqueduct.Core\trunk\Data\LinqExtensions.cs:116 Aqueduct.Core.Data.LinqExtensions.ToDataTable(IEnumerable`1 source) in D:\Repositories\aqueduct\Aqueduct.Core\trunk\Data\LinqExtensions.cs:49 Aqueduct.Platform.Web.packages.finance_carttranscriptorder_default.PopulateSearchResultsGrid(List`1 FilteredOrders) in D:\Repositories\aqueduct\Aqueduct.Platform.Web\trunk\packages\finance\carttranscriptorder\default.aspx.cs:47 Aqueduct.Platform.Web.packages.finance_carttranscriptorder_default.RunFilter() in D:\Repositories\aqueduct\Aqueduct.Platform.Web\trunk\packages\finance\carttranscriptorder\default.aspx.cs:101 Aqueduct.Platform.Web.packages.finance_carttranscriptorder_default.Page_Load(Object sender, EventArgs e) in D:\Repositories\aqueduct\Aqueduct.Platform.Web\trunk\packages\finance\carttranscriptorder\default.aspx.cs:22 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
+14 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35 System.Web.UI.Control.OnLoad(EventArgs e) +99 System.Web.UI.Control.LoadRecursive()
+50 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627发布于 2010-05-13 02:39:04
我怀疑它试图将代码转换为SQL。如果这仅仅是投影方面的事情,我建议您对LINQ- to -SQL位中所需的数据位进行简单的投影,然后使用AsEnumerable强制查询的其余部分在.NET本身中执行。在这一点上,你可以更自由地做这样的事情。因此,在本例中,您会得到如下内容:
var query = from ...
where ...
select new { p.OrderData, p.SomeOtherFields };
var transformed = query.AsEnumerable()
.Select(p => new {
OrderDate = (p.OrderDate.HasValue ? p.OrderDate.Value.ToString("yyyy-mm-dd")
: ""),
... });发布于 2010-05-13 12:27:58
当您在Linq to SQL中执行此操作时
OrderDate = (p.OrderDate.HasValue ?
p.OrderDate.Value.ToString("yyyy-mm-dd") : "")它实际上评估了案例的两个方面,但只返回给你“真”的案例。所以只要这样做,它就会避免可空,但仍然会给你正确的结果。
OrderDate = (p.OrderDate.HasValue ?
p.OrderDate.GetValueOrDefault(DateTime.Now).ToString("yyyy-mm-dd") : "")发布于 2010-05-13 03:08:19
所以,为了确认一下,FilteredResults是这样的:
FilteredResults = [query].AsEnumerable()对,是这样?
如果是这样,那么我能看到的唯一选项就是如果OrderID为null。它是一个可以为type的类型吗?所有其他(可以想象的)可以为空的属性似乎都有一个HasValue检查,或者根本没有使用(比如DeliverBy),所以我看不到任何其他的选择。
我唯一能建议的就是删除匿名类型的所有属性,然后一个接一个地添加它们,直到遇到错误为止。
顺便说一句,没有必要使用OrderDate.Value的Date属性,因为DateTime的ToString()函数可以很好地格式化日期,而不需要时间部分。
https://stackoverflow.com/questions/2821710
复制相似问题