我最近开始使用实体框架并认为它非常好但我对一些事情感到困惑。
我正在编写一个winforms-application,其中列出了列表中的人员列表,如果您单击某个人,则会在文本框中显示有关该人员的更多信息。到目前为止没什么好看的,但你应该能够编辑关于这个人的数据,这样数据绑定就很好了。
它工作得很好,但我对这是怎么做的正确方法感到困惑。首先,我确实喜欢这个:
var query = _context.Person.Where(c => c.Id == chosenId);
this.personBindingSource.DataSource = query.ToList();
然后我读了一下并尝试了:
var local = _context.Person.Local;
IEnumerable<Customer> enumerable = local.Where(c => c.Id == chosenId);
this.personBindingSource.DataSource = enumerable.ToList();
这个似乎也很好。
然后我看到有人提出类似的建议:
_context.Person.Load();
this.personBindingSource.DataSource = _context.Person.Local.ToBindingList();
我现在有点困惑,正确的方法是什么,这三者有什么区别?有人可以帮帮我吗?
答案 0 :(得分:2)
老实说,我从来不喜欢得到这个答案,因为它似乎是所有事情的答案,但在这种情况下,它确实是我能给出的唯一答案
Local为您提供了对未被delete标记的数据上下文所跟踪的当前元素的引用,实际上您要求的是当前已经加载到内存中的对象在上下文中,您可以在此处详细了解
DbSet(TEntity).Local Property
Load方法急切地加载目标上下文,你可以在这里阅读更多相关信息。
基本上,当您使用使用此方法创建的集合时,这将在您创建的任何实体和UI之间创建双向绑定。也就是说,UI中的任何更改都应自动反映在此集合中的相关实体中。您可以使用以下链接了解更多信息
BindingList(T) Class
DbExtensions.ToBindingList()
var query = _context.Person.Where(c => c.Id == chosenId);
this.personBindingSource.DataSource = query.ToList();
在幕后,以下内容正在进行中
在这里,您从数据库中抓取任何ID为Id的人,然后将其加载到您的应用程序中并创建列表
var local = _context.Person.Local;
IEnumerable<Customer> enumerable = local.Where(c => c.Id == chosenId);
this.personBindingSource.DataSource = enumerable.ToList();
在幕后,以下内容正在进行中
在这里,您抓住任何已经加载到上下文中的人这不会获得所有持久数据项,您必须在其他查询
_context.Person.Load();
this.personBindingSource.DataSource = _context.Person.Local.ToBindingList();
在幕后,以下内容正在进行中
除非您想将所有项目加载到内存中,否则这可能不是您想要做的事情,如果数据集增长得足够大,会导致程序运行速度变慢,并可能导致程序无法正常工作(不太可能出现问题)在大多数情况下的人,但是可能)
当您想要将与您的查询匹配的数据放入本地内存并且不需要UI和实体之间的链接时
< h3>第二当您已在上下文中运行查询并需要在其他地方使用它但不需要重新运行查询,因为它当前在内存中
当您想要将实体集的所有元素加载到内存中并在它们与控件之间创建双向数据绑定时
答案 1 :(得分:1)
你所拥有的第一个和第二个例子之间的唯一区别是一个延迟,一个不延迟。第三个是有点不同,因为它在您的数据库和控制数据源之间创建了一个双向绑定,有效地使datacontext跟踪更改列表(添加和删除)。
在您的所有示例中,只要您保留datacontext,就会跟踪对象本身的更改。
至于哪种方式是正确的,这取决于您的应用程序。根据您要完成的任务选择最适合您的方法