首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在SQL 2008中使用datetime执行Linq select new

如何在SQL 2008中使用datetime执行Linq select new
EN

Stack Overflow用户
提问于 2010-05-13 02:34:24
回答 3查看 2.8K关注 0票数 1

在我们的C#代码中,我最近更改了linq-to-sql select new查询中的一行,如下所示:

代码语言:javascript
复制
OrderDate = (p.OrderDate.HasValue ? 
    p.OrderDate.Value.Year.ToString() + "-" + 
    p.OrderDate.Value.Month.ToString() + "-" + 
    p.OrderDate.Value.Day.ToString() : "")

至:

代码语言:javascript
复制
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的更多信息:

代码语言:javascript
复制
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。

在常规代码中这样做效果很好:

代码语言:javascript
复制
if (o.OrderDate.HasValue)
    tempString += " " + o.OrderDate.Value.Date.ToString("yyyy-mm-dd");

下面是错误的堆栈跟踪。这是一所学校的一个大型系统的一部分,用于从DB检索订单以显示在屏幕上。

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-05-13 02:39:04

我怀疑它试图将代码转换为SQL。如果这仅仅是投影方面的事情,我建议您对LINQ- to -SQL位中所需的数据位进行简单的投影,然后使用AsEnumerable强制查询的其余部分在.NET本身中执行。在这一点上,你可以更自由地做这样的事情。因此,在本例中,您会得到如下内容:

代码语言:javascript
复制
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") 
                                     : ""),
   ... });
票数 4
EN

Stack Overflow用户

发布于 2010-05-13 12:27:58

当您在Linq to SQL中执行此操作时

代码语言:javascript
复制
OrderDate = (p.OrderDate.HasValue ? 
    p.OrderDate.Value.ToString("yyyy-mm-dd") : "")

它实际上评估了案例的两个方面,但只返回给你“真”的案例。所以只要这样做,它就会避免可空,但仍然会给你正确的结果。

代码语言:javascript
复制
OrderDate = (p.OrderDate.HasValue ? 
    p.OrderDate.GetValueOrDefault(DateTime.Now).ToString("yyyy-mm-dd") : "")
票数 1
EN

Stack Overflow用户

发布于 2010-05-13 03:08:19

所以,为了确认一下,FilteredResults是这样的:

代码语言:javascript
复制
FilteredResults = [query].AsEnumerable()

对,是这样?

如果是这样,那么我能看到的唯一选项就是如果OrderID为null。它是一个可以为type的类型吗?所有其他(可以想象的)可以为空的属性似乎都有一个HasValue检查,或者根本没有使用(比如DeliverBy),所以我看不到任何其他的选择。

我唯一能建议的就是删除匿名类型的所有属性,然后一个接一个地添加它们,直到遇到错误为止。

顺便说一句,没有必要使用OrderDate.ValueDate属性,因为DateTimeToString()函数可以很好地格式化日期,而不需要时间部分。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2821710

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档