Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么重置后旧值仍保留在此对象中?_C#_Asp.net_Sql Server_Visual Studio_Entity Framework - Fatal编程技术网

C# 为什么重置后旧值仍保留在此对象中?

C# 为什么重置后旧值仍保留在此对象中?,c#,asp.net,sql-server,visual-studio,entity-framework,C#,Asp.net,Sql Server,Visual Studio,Entity Framework,我已经向三个程序员展示了这个问题,我们都被难住了。我在foreach循环中调用Sql Server存储过程,结果始终与第一次调用相同即使我硬编码参数(删除循环),也只有第一个结果分配给所有后续调用。 存储过程由实体框架函数导入调用(EF4数据库首先使用设计器)。调用代码存在于作为类库的存储库中。存储库由单独的Asp.net webforms项目调用。问题代码如下所示: IEnumerable<WorkOrder> orders = _context.GetWorkOrders(Use

我已经向三个程序员展示了这个问题,我们都被难住了。我在foreach循环中调用Sql Server存储过程,结果始终与第一次调用相同即使我硬编码参数(删除循环),也只有第一个结果分配给所有后续调用。

存储过程由实体框架函数导入调用(EF4数据库首先使用设计器)。调用代码存在于作为类库的存储库中。存储库由单独的Asp.net webforms项目调用。问题代码如下所示:

IEnumerable<WorkOrder> orders = _context.GetWorkOrders(UserName, workOrder, customerCode).ToList();

OrderStatus lastStatus = new OrderStatus();

foreach (Order order in orders)
{
     lastStatus = _context.GetOrderStatus(order.OrderNumber).FirstOrDefault();
     order.LastOrderStatus = lastStatus.OrderStatus;
}
IEnumerable<WorkOrder> orders = _context.GetWorkOrders(UserName, workOrder, customerCode).ToList();

OrderStatus lastStatus = new OrderStatus();

foreach (Order order in orders)
{

    ObjectParameter workOrderParameter;
    if (wo.WorkOrder != null)
    {
        workOrderParameter = new ObjectParameter("WorkOrder", order.WorkOrder);
    }
    else
    {
       workOrderParameter = new ObjectParameter("WorkOrder", typeof(global::System.String));
    }

    lastStatus = _context.ExecuteFunction<OrderStatus>("GetOrderStatus", MergeOption.OverwriteChanges, workOrderParameter).FirstOrDefault();

    if (status != null)
    {
        order.LastOrderStatus = status.OrderStatus;
    }
}
IEnumerable orders=\u context.GetWorkOrders(用户名、工作顺序、客户代码).ToList();
OrderStatus lastStatus=新订单状态();
foreach(订单中的订单)
{
lastStatus=_context.GetOrderStatus(order.OrderNumber).FirstOrDefault();
order.LastOrderStatus=lastStatus.OrderStatus;
}
正如你所看到的,这是非常基本的东西。根据传入的订单号,我总是得到循环中第一个订单号的结果。我已经关闭了Ajax(我使用的Telerik控件的一部分),因为这在过去给我造成了令人困惑的错误。我真的希望你能提出一种方法来调试这个问题!提前谢谢


编辑:Daniel J.G.的评论让我想到了。现在我需要弄清楚如何应用Ladislav Mrnka的答案……尝试直接使用MergeOption调用ExecuteFunction。OverwriteChanges

我在回答我自己的问题(因为几天后没有其他人这样做)。该问题是由实体框架数据库第一设计器引起的。它生成缓存第一个存储过程结果的代码,从而在后续调用中导致错误结果

正如我在编辑我的问题中提到的,修复涉及替换ExecuteFunction使用的默认MergeOption参数。您需要使用MergeOption.OverwriteChanges,而不是默认的(我认为是MergeOption.PreserveChanges)

您可以在生成的代码中更改该参数,但每次重新生成设计器时,您所做的更改都将丢失。相反,我只是将生成的代码复制到我的repository类中,将MergeOption更改为OverwriteChanges,并停止使用生成的代码。最终结果如下所示:

IEnumerable<WorkOrder> orders = _context.GetWorkOrders(UserName, workOrder, customerCode).ToList();

OrderStatus lastStatus = new OrderStatus();

foreach (Order order in orders)
{
     lastStatus = _context.GetOrderStatus(order.OrderNumber).FirstOrDefault();
     order.LastOrderStatus = lastStatus.OrderStatus;
}
IEnumerable<WorkOrder> orders = _context.GetWorkOrders(UserName, workOrder, customerCode).ToList();

OrderStatus lastStatus = new OrderStatus();

foreach (Order order in orders)
{

    ObjectParameter workOrderParameter;
    if (wo.WorkOrder != null)
    {
        workOrderParameter = new ObjectParameter("WorkOrder", order.WorkOrder);
    }
    else
    {
       workOrderParameter = new ObjectParameter("WorkOrder", typeof(global::System.String));
    }

    lastStatus = _context.ExecuteFunction<OrderStatus>("GetOrderStatus", MergeOption.OverwriteChanges, workOrderParameter).FirstOrDefault();

    if (status != null)
    {
        order.LastOrderStatus = status.OrderStatus;
    }
}
IEnumerable orders=\u context.GetWorkOrders(用户名、工作顺序、客户代码).ToList();
OrderStatus lastStatus=新订单状态();
foreach(订单中的订单)
{
ObjectParameter workOrderParameter;
如果(工单!=空)
{
workOrderParameter=新对象参数(“WorkOrder”,order.WorkOrder);
}
其他的
{
workOrderParameter=新的ObjectParameter(“WorkOrder”,typeof(global::System.String));
}
lastStatus=_context.ExecuteFunction(“GetOrderStatus”,MergeOption.OverwriteChanges,workOrderParameter)。FirstOrDefault();
如果(状态!=null)
{
order.LastOrderStatus=status.OrderStatus;
}
}

我还发现有一种方法可以修改T4模板,使生成的代码使用正确的MergeOption参数。不过我还没试过。如果你感兴趣的话。

我回来为我自己的问题提供第二个答案确保实体密钥确实是每个实体的唯一标识符

在我的例子中,OrderStock实体缺少OrderID(以及StockID)作为实体键。通常,设计师从数据库中挑选主键字段,但我有一个独特的情况(我的实体基于视图)。由于我在实体键中省略了OrderID,因此我看到单个OrderStock实体的行重复


当我标记OrderID
Entity Key=True
时,重复的问题消失了。

您能演示一下如何填充订单吗?最可能的解释是GetWorkOrders没有做您认为它正在做的事情。我们需要查看GetWorkOrders()和GetOrderStatus()的代码我很确定不能在foreach循环中为迭代对象赋值。在遍历集合时,不能更改正在遍历的集合的内容。您可能正在填充另一个集合,或者需要使用for循环而不是foreach。@post_erasmus对象的实例没有被迭代,变量(引用对象的实例)被迭代,代码没有更改变量,只是更改它引用的对象。如果您试图更改iTreated变量,那么它将不允许您更改。