使用实体框架C#更新一行

如何解决使用实体框架C#更新一行

我正在使用C#和实体框架开发Windows窗体应用程序。我将客户购买的所有产品放入DGVNewOrder。对于DGVNewOrder中的evry产品,我想为每个出售的产品更新(按名称)库存数量。这是我尝试的代码:'''

Product pro = new Product(); 

for (int i = 0; i < DGVNewOrder.RowCount - 1; i++)
{
    string Soled_Product_name = DGVNewOrder.Rows[i].Cells[0].Value.ToString();
    pro = db.Products.Where(d => d.Name == Soled_Product_name ).FirstOrDefault();
    int y = Convert.ToInt32(pro.QteInStock); // QteInStock befor selling 
    int x = Convert.ToInt32(DGVNewOrder.Rows[i].Cells[2].Value); // the sold quantity 
    pro.QteInStock = y - x;  //  The remaining quantity after the sale
    db.Entry(pro).State = EntityState.Modified;
    db.SaveChanges();
 }

这里的问题是数量没有更新,但是所有产品的名称都更改为与DGVNewOrder中存在的第一个产品相同的名称 我也试过了

string Soled_Product_name = DGVNewOrder.Rows[i].Cells[0].Value.ToString();
          
Product c = (from w in db.Products
              where w.Name == Soled_Product_name
             select w).First();

int y = Convert.ToInt32(pro.QteInStock);
int x = Convert.ToInt32(DGVNewOrder.Rows[i].Cells[2].Value);
c.QteInStock = y - x;

db.Entry(pro).State = EntityState.Modified;
db.SaveChanges();

但给出相同的结果

解决方法

每当您有一个显示集合元素的控件(例如DataGridView,ListView)时,直接编辑控件中的项目通常不是一个好主意。造成这种情况的原因之一是,您需要主动从控件中获取更改的项目。例如,如果控件的显示发生更改,则列的顺序更改了,或者DataGridView中的行的顺序更改了,您必须主动找出更改的内容。

为此使用DataBinding更容易。将需要显示的项目放在BindingList<T>中,并将其分配给DataGridView.DataSource

DataGridViewColum.DataPropertyName包含应在列中显示的<T>属性的名称。只要操作员编辑一个值并接受它,就会通知您BindingList已更改。您无需再阅读DataGridView,您将自动知道在BindingList中已更新了完整的DataGridView。甚至添加或删除的行都在BindingList中

示例:

class OrderLine
{
    public int Id {get; set;}           // primary key of the OrderLine
    public int ProductId {get; set;}    // foreign key to the Product in this OrderLine
    public string ProductDescription {get; set;}
    public decimal ProductPrice {get; set;}
    public int NrOfItems {get; set;}
    public decimal TotalPrice => this.ProductPrice * this.NrOfItems;
}

您想要一个DataGridView来显示ProductId / ProductDescription / ProductPrice / NrOfItems / TotalPrice。

Operatos可以在DataGridView中添加新的OrderLine,或删除OrderLine。他们无法更改ProductId / ProductDescription / ProductPrice,但可以更改NrOfItems。

DataGridView dgv = new DataGridView();

// Add columns. This is some tedious work,usually it is best to let visual studio designer
// do this
dgv.Columns.Add(new DataGridViewColumn()
{
     Name = "columnProductId",DataProperty = nameof(OrderLine.ProductId),ReadOnly = true;
     ...
}
您所有列的

等。

现在用一些初始项填充您的datagridview:

IList<OrderLine> initialOrderLines = ...
var actualOrderLines = new BindingList<OrderLine(initialOrderLines);
dgv.DataSource = actualOrderLines;

如果没有初始订单行,请使用默认构造函数

然后,所有列都填充了实际的OrderLines。在编辑过程中,此集合会自动更新。如果操作员添加了新行,则会自动使用默认的OrderLine对其进行初始化,或者,如果您愿意,如果您订阅事件BindingList.OnAddingNew,则可以提供OrderLine。

最后,在操作员完成所有更改之后,他按下按钮:

void OnButtonReady_Clicked(object sender,...)
{
    // you can be certain the the BindingList is up-to-date
    // you don't have to fetch the items from the DataGridView anymore.
    this.UpdateStock(this.actualOrderLines);
}

private void UpdateStock(IEnumerable<OrderLine> actualOrderLines)
{
     foreach (OrderLine orderLine in actualOrderLines)
     {
         // TODO: update the stock
     }
}

有趣的是:如果更改了“列”顺序或对“行”进行了排序,那么这对您的实际OrderLines无效。如果将来您决定添加或删除列:没问题,您只知道您的信息在ActualOrderLines中,谁在乎如何向操作员显示信息,或他如何编辑信息。

最后一件好事:如果要通过简单的鼠标单击标题来对列进行排序,请考虑Nuget Package BindingListView

使用BindingList<T>代替BindingListView<T>

var initialOrderLines = ...
BindingListView<OrderLine> actualOrderLines = new BindingListView<OrderLine>(initialOrderLines);
this.dgv.DataSource = actualOrderLines;

宾果游戏:只要单击标题,项目的列属性就按升序或降序排列。甚至字形(显示排序顺序的小箭头)也正确显示。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-