And*_*ykh 6 c# sql-server entity-framework
我有一个Task表(称为Task_Task)和一个Field表(称为Core_Field).我还有Task_Field表,它将多个关系中的两个链接起来:
CREATE TABLE [dbo].[Task_Field](
[TaskId] [uniqueidentifier] NOT NULL,
[FieldId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_Task_Field] PRIMARY KEY NONCLUSTERED
(
[TaskId] ASC,
[FieldId] ASC
))
Run Code Online (Sandbox Code Playgroud)
我需要在这个表中插入一些记录.我是这样做的:
dbTask.Core_Field.Clear();
List<Core_Field> dbFields = _context.Core_Field
.Where(x => fields.Contains(x.FieldId)).ToList();
foreach (var field in dbFields)
{
dbTask.Core_Field.Add(field);
}
Run Code Online (Sandbox Code Playgroud)
这导致以下跟踪:
在这种情况下,我们有5个guid List<Guid> fields.我们看到这个疯狂值(这是查询运行的时间)的原因是因为Core_Field表中的行非常宽.他们有一些包含大量数据的二进制字段.如果我不检索这些字段,而是执行类似的操作:
var tmp = _context.Core_Field
.Where(x =>fields.Contains(x.FieldId))
.Select(x => x.SomeField).ToList();
Run Code Online (Sandbox Code Playgroud)
时间从~1000ms下降到几ms,大多数情况下为零.
正如您所看到的,插入记录也不会花费很长时间.
现在,我不需要该表中的整行.哎呀,我不需要那张桌子上的任何东西,我已经插入了所有的指南.
这就是EF关系的样子:
我想知道,如何有效地将这些记录添加到链接表.当然,我总是可以运行ExecuteSqlCommand方法,并且在不使用任务或字段实体的情况下进行更新,但我想知道是否有更多EF - 惯用的方法.
在这行代码中...
dbTask.Core_Field.Add(field)
Run Code Online (Sandbox Code Playgroud)
...dbTask.Core_Field由于延迟加载而加载。
如果禁用延迟加载,您将看到显着的性能提升:
_context.Configuration.LazyLoadingEnabled = false;
Run Code Online (Sandbox Code Playgroud)
但是,由于您“已经拥有要插入的所有 guid”,因此您可以通过使用存根实体(仅具有 Id 值的实体)获得更多(尽管少得多)。毕竟,EF 只需要 Id 值即可创建关联:
List<Core_Field> dbFields = fields.Select(f => new Core_Field { FieldId = f }).ToList();
foreach (var field in dbFields)
{
_context.Core_Fields.Attach(field);
dbTask.Core_Field.Add(field);
}
Run Code Online (Sandbox Code Playgroud)
需要注意的是:由于禁用了延迟加载,EF 不再跟踪dbTask.Core_Field。这意味着它不再发现重复项。通过延迟加载,EF 将仅忽略重复的连接记录。如果没有它,如果您尝试插入重复项,您将收到重复键错误。因此,您可能需要事先检查一下:
fields = _context.Code_Tasks
.Where(t => t.TaskId == id)
.SelectMany(t => t.Core_Field)
.Where(c => !fields.Contains(c.FieldId))
.Select(c => c.FieldId).ToList();
Run Code Online (Sandbox Code Playgroud)
这是一个相对轻量级的查询。
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |