C# 插入到链接表而不首先获取
我有一个任务表(称为Task_Task)和一个字段表(称为Core_Field)。我还有一个Task_字段表,它将多对多关系中的两个字段链接起来:C# 插入到链接表而不首先获取,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,我有一个任务表(称为Task_Task)和一个字段表(称为Core_Field)。我还有一个Task_字段表,它将多对多关系中的两个字段链接起来: CREATE TABLE [dbo].[Task_Field]( [TaskId] [uniqueidentifier] NOT NULL, [FieldId] [uniqueidentifier] NOT NULL, CONSTRAINT [PK_Task_Field] PRIMARY KEY NO
CREATE TABLE [dbo].[Task_Field](
[TaskId] [uniqueidentifier] NOT NULL,
[FieldId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_Task_Field] PRIMARY KEY NONCLUSTERED
(
[TaskId] ASC,
[FieldId] ASC
))
我需要在这个表中插入一些记录。我是这样做的:
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);
}
时间从约1000毫秒下降到几毫秒,在大多数情况下为零
正如您所看到的,插入记录也不会花费很长时间
现在,我不需要那张桌子上的整行。见鬼,我不需要那个表中的任何东西,我已经有了所有要插入的guid
这就是EF关系的样子:
我想知道,如何有效地将这些记录添加到链接表中。一、 当然,您可以始终运行方法,并在不使用任务或字段实体的情况下执行更新,但我想知道是否有更为EF惯用的方法来执行此操作。在这一行代码中
dbTask.Core_Field.Add(field)
…由于延迟加载,dbTask.Core_字段
已加载
如果禁用延迟加载,您将看到显著的性能提升:
_context.Configuration.LazyLoadingEnabled = false;
但是,由于“已经有了所有要插入的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);
}
这是一个相对较轻的查询。您只需要在Task_字段中插入记录?为什么不创建并插入该类型的对象?@FranciscoGoldenstein没有表示该对象的类型。请参见问题底部的图表,以可视化EF如何建模此关系。如果您需要按照描述的方式插入关系,则需要创建一个类来关联字段和任务。另外,该类还可以有关于关系的额外信息,这给了您更多的灵活性。@FranciscoGoldenstein,这是数据库优先。更改从数据库生成的EF模型通常是不可取的,因为这会使将来的数据库架构更改很难传播到该模型。我认为您可以做两件事:1)创建一个SP并通过对ID(字段和任务)调用它。2) 创建mapping类并手动映射它。就在money上。谢谢请注意,只有当任务已经存在时,延迟加载才是一个问题。如果它是作为同一事务的一部分插入的,我不会观察到分析器中的延迟加载。在本例中,是存根实体保存了该节目。实际上,我对插入和更新都使用了相同的代码,所以一切都很好。我想知道你能否帮我解决这个问题的另一个方面。在这段代码之前,我有一行
dbTask.Core_Field.Clear()代码>-删除与任务关联的旧字段集。此代码现在不会导致db调用(惰性加载已关闭)。如何恢复此功能?老鼠!那就难多了。我碰巧遇到了一个实体,但您可以对一组实体应用相同的技巧。在您的例子中,我倾向于执行原始SQL语句,删除一个任务的所有连接记录。
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);
}
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();