保持 DbContext 对 DataGridView 的打开



我有一个DataGridView,DataGridView的数据源是我通过上下文从实体框架(V6(获得的BindingList。Person.Local.ToBindingList((. 将数据源设置为此 BindingList 后,我将释放上下文,因为我读到保持上下文打开状态是一种不好的做法。

因此,如果我想添加新行,我会单击绑定导航器附带的"添加"按钮,该按钮是在我将"人员"对象数据源拖动到我的 Windows 窗体时创建的。 每次单击"添加"按钮时,我都会收到一个异常,告诉我上下文已被释放。 使用 DataGridView 时,是否需要始终保持上下文处于打开状态?哦,还有:数据源可能会在运行时更改,具体取决于列表框项的选择。

此外,当上下文已处理并且我从 DataGridView 编辑了一行时,我如何找出(多次更改后(哪一行已更改? 我尝试做:

foreach(DataGridViewRow row in peopleDataGridView.Rows)
{
People item = (People)row.DataBoundItem;
if (item != null)
{
db.People.Attach(item);
}
}
db.SaveChanges();

。但是SaveChanges((没有识别任何更改。但是,如果我强制每个附加项目进入"修改"状态,它就可以工作。但我不想将 100 个项目更改为"修改",如果只有一个项目被实际修改。

有什么想法吗?

编辑 1哦,好吧,所以我更改了我的代码以始终保持上下文打开(或者至少只要表单显示(。 现在,我遇到了一个不同的问题(人们可能有很多工作(:

private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
People p = (People)listBox1.SelectedItem;
if(p != null)
{
//jobBindingSource.Clear(); this caused another error at runtime...
db.Entry(p).Collection(b => b.Job).Load();
jobBindingSource.DataSource = db.Job.Local.ToBindingList();
}
}

绑定到此 jobBindingSource 实例的 DataGridView 显示人员的正确作业,但除了以前选择的人员的作业之外。我尝试清除((条目,但是如果我这样做并单击同一个人两次,则datagridview有时开始根本不显示任何条目。一种奇怪的行为。 我现在做错了什么?

编辑 2好的...我自己找到了解决方案。但我拒绝接受这是正确的方法:

private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
People p = (People)listBox1.SelectedItem;
if(p != null)
{
db.Dispose();
db = new PeopleJobsEntities();
db.People.Attach(p);
db.Entry(p).Collection(person => person.Job).Load();
jobBindingSource.DataSource = db.Job.Local.ToBindingList();
}
}

只有当我处理上下文并重新打开它时,整个事情才会起作用。原因是如果我清除本地缓存(db。Job.Local(,即使我使用 Load(( 方法,它的条目也不会再次重新加载。有没有办法强制重新加载实体?

虽然我尽量不让 DBContext 长时间保持打开状态,但对于数据网格,您没有太多选择。 我将网格的DataSource属性设置为IQueryable<T>,然后所有编辑、删除和添加都由网格和上下文本身处理。 您只需要在要保留更改时调用dbContext.SubmitChanges()。 每次用户离开行时,都可以通过在RowLeaveRowValidated事件上保存。 或者,您可以在关闭窗体时保存。 但也要确保在关闭表单时也调用dbContext.Dispose()

若要了解哪些行发生了更改,可以通过执行以下操作来查看返回的ChangeSet

var changes = dbContext.GetChangeSet();
dbContext.SubmitChanges();
  • 请确保您的项目不为 null。

  • 检查连接字符串。

并且,试试这个:

db.People.Add(item);

而不是:

db.People.Attach(item);

好的,多亏了@jaredbaszler我想出了这个适合我的解决方案。 我决定让 DbContext 一直保持活力。为了清除本地缓存,我在循环中分离了内部的每个实体。我认为这是一种非常恶心的方式。一定有更好的方法...

这是我所拥有的:

PeopleJobsEntities db;
public FormTest()
{
InitializeComponent();
db = new PeopleJobsEntities();
db.Database.Log = Console.Write;
db.People.Load();
List<People> peoplelist = db.People.Local.ToList();
listBox1.DataSource = peoplelist;
}
private void FormTest_FormClosing(object sender, FormClosingEventArgs e)
{
if (db != null)
db.Dispose();
}
private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
People p = (People)listBox1.SelectedItem;
if(p != null)
{
List<Job> oldlist = db.Job.Local.ToList();
foreach (Job j in oldlist)
{
db.Entry(j).State = EntityState.Detached;
}
db.Entry(p).Collection(b => b.Job).Load();
jobBindingSource.DataSource = db.Job.Local.ToBindingList();
}
}
private void jobBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
foreach(DataGridViewRow row in jobDataGridView.Rows)
{
if(row != null && row.DataBoundItem != null)
{
Job j = (Job)row.DataBoundItem;
if(db.Entry(j).State == EntityState.Added)
{
if(j.People.Count == 0)
{
People people = (People)listBox1.SelectedItem;
if (people != null)
j.People.Add(people);
}
}
}
}
db.SaveChanges();
}
  • 编辑条目有效
  • 添加新条目有效
  • 删除条目有效

相关内容

  • 没有找到相关文章

最新更新