我需要在数据库的 2 个表中插入一行。这两个表之间的关系是一对多。这是他们的模型:
public partial class Task
{
public Task()
{
TaskOwner = new HashSet<TaskOwner>();
}
public int Id { get; set; }
public string Action { get; set; }
public int ActualEffort { get; set; }
public DateTime AssignationDate { get; set; }
public int EstEffort { get; set; }
public DateTime EstEnd { get; set; }
public bool IsComplete { get; set; }
public int ProjectId { get; set; }
public string Status { get; set; }
public virtual ICollection<TaskOwner> TaskOwner { get; set; }
public virtual Project Project { get; set; }
}
public partial class TaskOwner
{
public int Id { get; set; }
public int EmployeId { get; set; }
public int TaskId { get; set; }
public virtual Employe Employe { get; set; }
public virtual Task Task { get; set; }
}
这是上下文:
modelBuilder.Entity<Task>(entity =>
{
entity.HasIndex(e => e.ProjectId)
.HasName("FKTask25514");
entity.Property(e => e.Id)
.HasColumnName("id")
.HasColumnType("int(10)");
entity.Property(e => e.Action)
.IsRequired()
.HasColumnName("action")
.HasColumnType("varchar(255)");
entity.Property(e => e.ActualEffort)
.HasColumnName("actual_effort")
.HasColumnType("int(10)");
entity.Property(e => e.AssignationDate).HasColumnName("assignation_date");
entity.Property(e => e.EstEffort)
.HasColumnName("est_effort")
.HasColumnType("int(10)");
entity.Property(e => e.EstEnd).HasColumnName("est_end");
entity.Property(e => e.IsComplete).HasColumnType("tinyint(1)");
entity.Property(e => e.ProjectId)
.HasColumnName("project_id")
.HasColumnType("int(10)");
entity.Property(e => e.Status)
.IsRequired()
.HasColumnName("status")
.HasColumnType("varchar(255)");
entity.HasOne(d => d.Project)
.WithMany(p => p.Task)
.HasForeignKey(d => d.ProjectId)
.OnDelete(DeleteBehavior.Restrict)
.HasConstraintName("FKTask25514");
});
modelBuilder.Entity<TaskOwner>(entity =>
{
entity.ToTable("Task_Owner");
entity.HasIndex(e => e.EmployeId)
.HasName("FKTask_Owner320287");
entity.HasIndex(e => e.TaskId)
.HasName("FKTask_Owner395416");
entity.Property(e => e.Id)
.HasColumnName("id")
.HasColumnType("int(10)");
entity.Property(e => e.EmployeId)
.HasColumnName("employe_id")
.HasColumnType("int(10)");
entity.Property(e => e.TaskId)
.HasColumnName("task_id")
.HasColumnType("int(10)");
entity.HasOne(d => d.Employe)
.WithMany(p => p.TaskOwner)
.HasForeignKey(d => d.EmployeId)
.OnDelete(DeleteBehavior.Restrict)
.HasConstraintName("FKTask_Owner320287");
entity.HasOne(d => d.Task)
.WithMany(p => p.TaskOwner)
.HasForeignKey(d => d.TaskId)
.OnDelete(DeleteBehavior.Restrict)
.HasConstraintName("FKTask_Owner395416");
});
一个任务可以由多个任务所有者拥有。我尝试过这个方法:
Models.Task task = new Models.Task()
{
Status = tde.Status.ToString(),
Action = tde.Subject.ToString(),
IsComplete = tde.IsComplete,
EstEnd = tde.DueDate.GetValueOrDefault(DateTime.Now),
AssignationDate = tde.DateTimeCreated.Date,
ActualEffort = Convert.ToInt32(tde.ActualWork),
EstEffort = Convert.ToInt32(tde.TotalWork),
ProjectId = (from p in _context.Project
where p.ProjectSapId == Convert.ToInt32(tde.BillingInformation)
select p.Id).First(),
};
Models.TaskOwner taskOwner = new Models.TaskOwner()
{
EmployeId = employee.Id,
};
task.TaskOwner.Add(taskOwner);
_context.Task.Add(task);
然后将其保存到数据库中,但我总是会遇到此错误:
self referencing loop detected with type 'Models.TaskOwner' . Path '[6].taskOwner[0].employe.taskOwner'.
如果可以的话,我会使用刚刚创建的任务的 id 并将其链接到 taskOwner 模型,但由于 id 是自动生成的,所以我不能或至少不知道如何生成。我究竟做错了什么?完成我想要完成的任务的正确方法是什么?
最佳答案
因此,一个Task
有零个或多个TaskOwners
。每个 TaskOwner
都只有一个 Task
。没有 Task
就没有 TaskOwners
。
这意味着,如果数据库中已有一个 TaskOwner
,则不能让它拥有第二个 Task
。不过,您可以让它拥有另一项 Task
,而不是它现在拥有的任务。
如果向数据库引入(添加)一个与数据库中现有对象有关系的对象,则可以使用相关对象的 Id 或该对象本身(当然,它具有非零值) ID)。
如果相关对象也是新的,只需将相关对象分配给您要添加的对象即可。您不必单独添加相关对象。
请注意,只要您没有使用 SaveChanges,您就无法使用任何新对象的 Id。
引入一个拥有现有任务和现有员工的 TaskOwner
using (var dbContext = new MyDbContext())
{
int employeeId = FetchEmployeeId(...);
int taskId = FetchTaskId(...);
TaskOwner introducedTaskOwner = dbContext.TaskOwners.Add(new TaskOwner()
{
// don't fill the ID!
EmployeeId = employeeId,
TaskId = taskId,
... // other properties
});
dbContext.SaveChanges();
// now the introduced task owner has an Id!
return introducedTaskOwner;
}
引入一个任务所有者和一个新任务。使用现有员工
现在你不能填写TaskId,而是填写一个Task:
using (var dbContext = new MyDbContext())
{
int employeeId = FetchEmployeeId(...);
TaskOwner introducedTaskOwner = dbContext.TaskOwners.Add(new TaskOwner()
{
// don't fill the TaskOwner ID!
EmployeeId = employeeId,
// Give the Task owner a non-existing Task:
Task = new Task()
{
// don't fill the Task ID!
// don't fill the collection of TaskOwners
... // fill other Task properties
}
... // other task owner properties
});
dbContext.SaveChanges();
// now both the task owner and the task are introduced. Both have an ID
Debug.Assert(introducedTaskOwner.Id != 0);
Debug.Assert(intrducedTaskOwner.TaskId != 0);
Debug.Assert(introducedTaskOwner.Task.Id != 0);
}
如果您愿意,您可以先引入任务,然后引入任务所有者。只要您没有使用 SaveChanges,您就不能使用任何 Id。
using (var dbContext = new MyDbContext())
{
int employeeId = FetchEmployeeId(...);
Task introducedTask = dbContext.Tasks.Add(new Task()
{
// don't fill the Task ID!
TaskOwners = new List<TaskOwner>(); // This Task has no owners yet
... // fill other Task properties
});
TaskOwner introducedTaskOwner = dbContext.TaskOwners.Add(new TaskOwner()
{
// don't fill the TaskOwner ID!
EmployeeId = employeeId,
// Give the Task owner a the introduced task
Task = introducedTask,
... // other task owner properties
});
dbContext.SaveChanges();
}
您也可以反过来做:您可以将 TaskOwner 添加到现有(或新添加的)任务
using (var dbContext = new MyDbContext())
{
int employeeId = FetchEmployeeId(...);
// get existing task:
Task existingTask = dbContext.Tasks
.Where(task => task.ActualEffort > ...)
.OrderBy(task => task.ActualEffort)
.FirstOrDefault();
// add an owner to the task owners collection:
existingTask.TaskOwners.Add(new TaskOwner()
{
// don't fill the TaskOwner ID!
EmployeeId = employeeId,
// no need to fill the TaskId, nor the Task
// Entity Framework knows the Task to which it belongs, because you
// add it to the TaskOwners collection
...
});
dbContext.SaveChanges();
}
结论:只要没有Id,就使用完整的对象。如果尚未添加对象, Entity Framework 将添加它
关于mysql - 当id自动生成时,如何使用 Entity Framework 核心插入数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45592206/