【问题标题】:updating category id for the product instead of creating new id更新产品的类别 ID,而不是创建新的 ID
【发布时间】:2011-08-24 16:18:30
【问题描述】:

我有两张桌子

产品

                product_id
                product_Name
                product_Price
                product_Description
                product_image
                category_id

另一个表

                 category
                 category_id
                 category_name
                 category_description

我有一个包含三个文本框的表单(比如 tbProductPrice、tbProductName、tbProductdescription)一个组合框(cbcategorytypes)两个按钮一个编辑,另一个是保存按钮.. 我正在尝试更新产品表以及 category_id

当我单击编辑按钮时,类别名称会加载到组合框中

当我们单击保存按钮时,文本框中的任何值将在产品表中与类别一起更新,我已经完成了以下代码...

              using (var vareditcontext = new abcEntities())
            {
                pictureBox1.Enabled = true;
                pictureBox1.Visible = true;
                Image image = pictureBox1.Image;
                byte[] bit = null;

                bit = imageToByteArray(image);
                product1 pd = vareditcontext.product1.Where(p => p.product_Id == productid
                                     && p.category_Id == productcategoryid).First();


                string category = cbcategorytypes.Text;

                var c = new category { category_Name = category }; //problem at this line 

                pd.category = c;
                pd.product_Name = tbProductName.Text;
                decimal price = Convert.ToDecimal(tbProductPrice.Text);
                pd.product_Price = price;
                pd.product_Description = tbProductdescription.Text;
                pd.product_Image = bit;
                vareditcontext.SaveChanges();                 
                this.Close();
            }

当我单击保存按钮时,我遇到了这样的异常..

参数超出范围异常 ..

我收到此错误是因为当我编辑并尝试将产品详细信息与类别名称一起保存时,新的类别名称将存储在数据库中.....而不是更新当前的...

我该如何解决这个问题..我的意思是不存储我想将已经存在的类别设置到产品的新项目...

linq 可以吗 ....

任何人都可以帮助解决这个问题..

非常感谢....

【问题讨论】:

    标签: c# .net linq entity-framework linq-to-entities


    【解决方案1】:

    我假设category_id 是您的category 实体的Key 属性。如果您只将category_name 加载到组合框中,您实际上需要从数据库中加载Category,因为当您将类别分配给产品时,EF 必须知道键值:

    product1 pd = vareditcontext.product1
        .Where(p => p.product_Id == productid
            && p.category_Id == productcategoryid)
        .First();
    
    category c = vareditcontext.categories
        .Where(cat => cat.category_name == cbcategorytypes.Text)
        .First(); // let's hope the name is unique to pick not the wrong one
    
    pd.category = c;
    // ...
    vareditcontext.SaveChanges();
    

    您也可以只加载 category_id,然后利用 Dennis 的方法创建一个存根类别并将其附加到上下文:

    product1 pd = vareditcontext.product1
        .Where(p => p.product_Id == productid
            && p.category_Id == productcategoryid)
        .First();
    
    int categoryid = vareditcontext.categories
        .Where(cat => cat.category_name == cbcategorytypes.Text)
        .Select(cat => cat.category_id)
        .First();
    
    var c = new category { category_id = categoryid };
        // stub entity must have at least the key property set
    vareditcontext.categories.Attach(c);
    
    pd.category = c;
    // ...
    vareditcontext.SaveChanges();
    

    如果您要将product 表中的category_id 列作为外键属性公开到您的product 模型类中,您只需设置category_id

    product1 pd = vareditcontext.product1
        .Where(p => p.product_Id == productid
            && p.category_Id == productcategoryid)
        .First();
    
    int categoryid = vareditcontext.categories
        .Where(cat => cat.category_name == cbcategorytypes.Text)
        .Select(cat => cat.category_id)
        .First();
    
    pd.category_id = categoryid;
    // ...
    vareditcontext.SaveChanges();
    

    【讨论】:

      【解决方案2】:

      您需要从上下文加载类别或将您即时创建的类别附加到上下文。否则 EF 假定您要创建并存储一个新的。

      ...
      var c = new category { category_Name = category };
      vareditcontext.Attach(c);
      pd.category = c;
      ...
      

      在 MSDN,您可以阅读有关 Attaching and Detaching Objects 的更多信息。

      【讨论】:

      • 这正是你所做的。 DbContext.Attach() != DbContext.Add()。它不会添加一个新的,它会将您创建的一个附加到上下文中,假设它已经存在数据库,从而节省您从数据库中获取它的往返行程。如果事情仍然不清楚,请阅读它。
      • 如果要将新对象存储到数据库中,请使用 Add()。如果您想附加一个类似于数据库中已经存在的对象而不需要预先加载它,请使用Attach()。如果您仍然不确定,请按照我的答案中的链接阅读文档。
      • 这是最简单的方法 如果 category_name 是主键属性。谁知道?如果不是,它就不起作用。
      • 是的。如果在此位置不知道主键,则必须从数据库中获取类别或至少其键。好点子。
      猜你喜欢
      • 2016-03-20
      • 1970-01-01
      • 1970-01-01
      • 2021-07-02
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      相关资源
      最近更新 更多