Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.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# Can';在ASP.NETMVC3项目中使用实体框架保存更改_C#_Asp.net Mvc 3_Entity Framework_Ef Code First_Savechanges - Fatal编程技术网

C# Can';在ASP.NETMVC3项目中使用实体框架保存更改

C# Can';在ASP.NETMVC3项目中使用实体框架保存更改,c#,asp.net-mvc-3,entity-framework,ef-code-first,savechanges,C#,Asp.net Mvc 3,Entity Framework,Ef Code First,Savechanges,首先学习asp.NETMVC3+EF代码。我对两者都是新手。我的例子是微不足道的,但我仍然不能使它工作。缺少一些简单而明显的东西 我有一门课: public class Product { [HiddenInput(DisplayValue = false)] public int ProductID { get; set; } [Required(ErrorMessage = "Please enter a product name")] public s

首先学习asp.NETMVC3+EF代码。我对两者都是新手。我的例子是微不足道的,但我仍然不能使它工作。缺少一些简单而明显的东西

我有一门课:

 public class Product
 {
    [HiddenInput(DisplayValue = false)]
    public int ProductID { get; set; }

    [Required(ErrorMessage = "Please enter a product name")]
    public string Name { get; set; }

    [Required(ErrorMessage = "Please enter a description")]
    [DataType(DataType.MultilineText)]
    public string Description { get; set; }

    [Required]
    [Range(0.01, double.MaxValue, ErrorMessage = "Please enter a positive price")]
    public decimal Price { get; set; }

    [Required(ErrorMessage = "Please specify a category")]
    public string Category { get; set; }
}
和一个
DbContext

public class EFDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }
}
它让我看到产品列表,打开编辑视图,根据属性集验证所有内容

当我保存已验证的更改时,它会转到Http Post
Edit
方法并进行必要的
SaveChanges()

它没有抛出任何异常,它继续并将我重定向到产品列表

编辑的项目保持不变


基础数据库(通过
web.config
中的
connectionstrings
连接)也保持不变。

您需要附加在EF外部创建的实体实例,并告知EF它已被修改

public void SaveProduct(Product product)
{
    if (product.ProductID == 0)
    {
        context.Products.Add(product);
    }
    else
    {
        context.Products.Attach(product);
        context.Entry(product).State = EntityState.Modified;
    }

    context.SaveChanges();
}

您应该在
保存更改之前将
产品
实例附加到上下文中

public void SaveProduct(Product product)
{
    if (product.ProductID == 0)
        context.Products.Add(product);
    else
    {    
        context.Products.Attach(product);
        context.Entry(product).State = EntityState.Modified;
    }
    context.SaveChanges();
}

的确,你应该附上

假设您调用Edit(1)。您的控制器将从DB加载ID=1的产品,并根据其属性(您在视图中声明的属性)生成HTML视图。 一旦您离开Edit(int productId)方法,并且您的视图显示在浏览器中,您的DbContext就丢失了具有该ID的产品;它已经超出了范围。 如果随后对产品进行更改并提交表单,ASP MVC将根据表单字段(以及其他内容)拼凑出一个新的产品对象,并将该对象传递给Edit(Product)方法。 由于这是一个全新的产品对象,而且旧产品对象已经超出了范围,因此DbContext不知道新产品与数据库的关系:它是新对象吗?它是现有对象吗?如果它存在,它是否有任何更改?
如果附加Product对象并将其状态设置为modified,则DbContext可以开始检查哪些属性已更改。

试图找出我是否使用了不同的上下文…似乎是
AdminController
中的
存储库
具有不同的
GetHashCode()
如果在两个不同的
编辑方法中选中,
不知道是否可以说smthI利用了Ninject(也研究DI),ProductID的默认值不是Int32.MinValue,而不是0吗?还有,您将如何以及何时将存储库传递给AdminController构造函数?即使如此,情况并非如此,因为我只尝试编辑现有行,您为什么说它是在EF之外创建的?在
edit
“Get request”方法中,我让实体像下面这样进行编辑
Product=repository.Products.FirstOrDefault(p=>p.ProductID==ProductID)
。它来自EFcontext@horghMVC Model binder在调用
Edit
方法时创建
Product
的新实例。请记住,web是无状态的。
Get
Post
请求不会发生在同一控制器实例内。因此,在这种场景中使用
Attach
必须非常常见ario?还是有更好的整体方法?@horgh正确的方法是使用ViewModels与视图交互,并将它们来回映射到控制器中的模型实例。
public void SaveProduct(Product product)
{
    if (product.ProductID == 0)
    {
        context.Products.Add(product);
    }
    else
    {
        context.Products.Attach(product);
        context.Entry(product).State = EntityState.Modified;
    }

    context.SaveChanges();
}
public void SaveProduct(Product product)
{
    if (product.ProductID == 0)
        context.Products.Add(product);
    else
    {    
        context.Products.Attach(product);
        context.Entry(product).State = EntityState.Modified;
    }
    context.SaveChanges();
}