9

我需要Guid从一个查询中获取我的 ID(类型):

var firstQuery = 
    from rooms in myEntityContext.Room.Where(t => t.fldClosed == 0)
    join conts in myEntityContext.Cont on rooms.ID equals conts.ItemID
    select new
    {
        ContPrice = conts.Price,
        RoomPrice = rooms.Price
        IDs = rooms.ID
    };

foreach (var t in firstQuery)
{
    t.RoomPrice  = t.ContPrice;
}

然后我对其进行一些操作(更新价格),最后我使用 ID 进行第二次查询。第二个查询不包含这些 ID。我以这种方式实现了这个问题:

var myIDs = firstQuery.Select(cr => cr.IDs).ToList();

我的第二个查询是:

var secondQuery = 
    from rooms in myEntityContext.Room.Where(t => t.fldClosed == 0) 
    where !myIDs.Contains(rooms.fldID)                                   
    join conts in myEntityContext.Cont on rooms.ID equals conts.ItemID
    select new
    {
       RoomPrice = conts.fldPrice,
       IDs = rooms.ID
    };

当我在调试器模式下运行此代码并到达此行时:

var myIDs = firstQuery.Select(cr => cr.IDs).ToList();

...引发异常:

NullReferenceException
对象引用未设置为对象的实例。

似乎它与第二个查询有关,因为当我将第二个查询转移到一个单独的方法并将 ID 传递给它时,一切正常,但我不明白为什么它应该考虑一些写在变量之后的查询初始化。

整个代码是:

var calcDate = DateTime.Now.AddDays(-1);

var firstQuery = 
    from rooms in myEntityContext.Room.Where(t => t.fldClosed == 0)
    join conts in myEntityContext.Cont on rooms.ID equals conts.ItemID
    where conts.date == calcDate
    select new
    {
        ContPrice = conts.Price,
        RoomPrice = rooms.Price
        IDs = rooms.ID
    };

foreach (var t in firstQuery)
{
    t.RoomPrice = t.ContPrice;
}

var myIDs = firstQuery.Select(cr => cr.IDs).ToList();


var secondQuery = 
    from rooms in myEntityContext.Room.Where(t => t.fldClosed == 0) 
    where !myIDs.Contains(rooms.fldID)                                   
    join conts in myEntityContext.Cont on rooms.ID equals conts.ItemID
    where conts.date == calcDate && conts.Code = "01"
    select new
    {
       RoomPrice = conts.fldPrice,
       IDs = rooms.ID
    };

foreach (var t in secondQuery)
{
    ContPrice = Conts.Price,
    RoomPrice = Rooms.Price
}

myEntityContext.SaveChanges();

这是我的堆栈跟踪,如果有用的话:

Financial.UI.dll!Financial.UI.Services.Hotels.HotelServiceProxy.CalcProxy.DoCalc(System.DateTime calcDate) 第 5055 行 C#
Financial.UI.dll!Financial.UI.Pages.Hotel.NightsCalculationPage.CallbackMethod_DoCalc() 第 65 行 + 0x37 字节 C#
[本机到托管转换]  
Web.UI.dll!Web.UI.SystemCallback.ProcessCallback() 第 228 行 + 0x3b 字节 C#
Web.UI.dll!Web.UI.SystemCallbackHandler.ProcessRequest(System.Web.HttpContext context) 第 68 行 + 0x12 字节 C#
System.Web.dll!System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() + 0x156 字节    
System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step, ref bool completedSynchronously) + 0x46 字节
System.Web.dll!System.Web.HttpApplication.PipelineStepManager.ResumeSteps(System.Exception 错误) + 0x342 字节
System.Web.dll!System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext context, System.AsyncCallback cb) + 0x60 字节
System.Web.dll!System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest WR, System.Web.HttpContext context) + 0xbb 字节   
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) + 0x1f3 字节   
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) + 0x1f 字节  
[本机到托管转换]  
[管理到本地转换]  
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) + 0x350 字节   
System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) + 0x1f 字节  
[Appdomain 过渡]  
4

5 回答 5

5

好吧,堆栈跟踪很有用:我假设您发布的代码在DoCalc()方法中。但是,您发布的行不可能是代码中的第 5055 行:

var myIDs = firstQuery.Select(cr => cr.IDs).ToList();

NullReferenceException在此行上出现 a ,要么firstQuery必须为 null ,要么firstQuery.Select(cr => cr.IDs)必须返回 null ...

但是,如果是这种情况,您将ArgumentNullException在两种情况下都得到a ,而不是NullReferenceException. 所以这不是错误所在。


此外,您的代码甚至不应该运行!

例如,在以下部分中,您应该会收到编译时错误:

foreach (var t in firstQuery)
{
    t.RoomPrice = t.ContPrice;
}

无法将属性或索引器“AnonymousType#1.RoomPrice”分配给 - 它是只读的

而你在这里想要做什么......我不知道:

foreach (var t in secondQuery)
{
    ContPrice = Conts.Price,
    RoomPrice = Rooms.Price
}

最有可能发生的事情

你有一个nullinmyEntityContext.Room或 in myEntityContext.Cont。查看他们的内容并验证这一点。如果您仍然不确定,当您收到异常时,请单击 Visual Studio(在异常窗口上)中的“将异常详细信息复制到剪贴板”并将其粘贴到您的问题中。

于 2013-02-27T15:58:41.647 回答
3

此代码无法编译。因此,假设在某一时刻它确实编译了,并且您的所有 Rooms 和 Cont 都是实际实例,其中没有空对象,则可能是使用匿名返回;

尝试这个

public class QueryResult
{
    public decimal ContPrice; //whatever your types are

    public decimal RoomPrice;

    public int IDs;
}

然后像这样使用它:

var firstQuery =
    from rooms in myEntityContext.Room.Where(t => t.fldClosed == 0)
    join conts in myEntityContext.Cont on rooms.ID equals conts.ItemID
    where conts.date == calcDate
    select new QueryResult
                {
                    ContPrice = conts.Price,
                    RoomPrice = rooms.Price,
                    IDs = rooms.ID
                };

var firstQueryResult = firstQuery.ToList();

foreach (var t in firstQueryResult)
{
    t.RoomPrice = t.ContPrice;
}

正如其他人所说,避免多次列举。

还要删除第二个查询并最初获得第一个工作......第二个有一些问题。首先,结果您再次拥有匿名类型。这是一种滥用,因为它们应该被用于 inter-linq;你应该解决一个强类型。第二,

... && conts.Code = "01"

不编译,应该是:

conts.Code.Equals("01")

我还建议将您的查询分解成更小的部分;也许是这样的

var roomsOpenQuery = myEntityContext.Room.Where(t => t.fldClosed == 0);
var roomsOpenQueryResolved = roomsOpenQuery.ToList();
var contQuery = myEntityContext.Cont
    .Where(t => roomsOpenQueryResolved.Any(r => r.ID == t.ItemID))
    .Where(x => x.date == calcDate);


var availableRooms =
    contQuery
        .Join(roomsOpenQueryResolved,
                c => c.ItemID,
                r => r.ID,
                (c, r) => new AvailableRoom()
                            {
                                ContPrice = c.Price,
                                RoomPrice = r.Price,
                                IDs = c.ItemID
                            })
        .ToList();


//Price Adjustment etc...
于 2013-03-02T08:29:07.943 回答
2

我假设var FirstQuery解析为 IEnumerable<out T>。

您不能Enumerable多次访问 a 的内容。

尝试在第一个查询中创建一个列表:

var FirstQuery = (from rooms in myEntityContext.Room.Where(t => t.fldClosed == 0)                                    
    join Conts in myEntityContextt.Cont on rooms.ID equals Conts.ItemID
    select new
    {
        RoomPrice = Conts.fldPrice,
        IDs = rooms.ID
    }).ToList();

如果此行失败,则 myEntityContext.Mark 或 myEntityContext.Cont 可能是空对象

于 2013-02-19T11:35:03.113 回答
1

IDs IDs = rooms.ID 可能为空。

尝试添加: var myIDs = FirstQuery.ToList().Select(Cr => Cr.IDs).ToList();

于 2013-02-26T15:25:18.140 回答
1
var myIDs = new List<int>();
if( firstQuery.Count() > 0)
myIds =  firstQuery.Select(cr => cr.IDs).ToList();
于 2013-02-27T16:16:57.877 回答