Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 插入到链接表而不首先获取_C#_Sql Server_Entity Framework - Fatal编程技术网

C# 插入到链接表而不首先获取

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

我有一个任务表(称为Task_Task)和一个字段表(称为Core_Field)。我还有一个Task_字段表,它将多对多关系中的两个字段链接起来:

    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();