C# EF 6使用现有外键添加对象
我使用的是实体框架,我有表Employee和Position。员工有对职位的引用C# EF 6使用现有外键添加对象,c#,entity-framework,C#,Entity Framework,我使用的是实体框架,我有表Employee和Position。员工有对职位的引用 Table("Employee")] public partial class Employee { public int Id { get; set; } public string Name { get; set; } public string Surname { get; set; } public string Phone { get; set; } public
Table("Employee")]
public partial class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Phone { get; set; }
public int Position_Id { get; set; }
public decimal Salary { get; set; }
public virtual Position Position { get; set; }
及
正在添加控制器:
var toModel = viewModel.ToEmployee();
_employeeService.Create(toModel);
但这创造了新的员工和新的职位,但我只想有新的员工以及员工和职位之间的关系。如何在EF中实现它
当我在ToEmployee()中尝试此功能时:
返回错误InvalidColumn
谢谢你的帮助 在数据库中查找Position对象并将其传递给ToEmployee()方法
显然,一个职位有零名或多名员工,而每个员工只属于一个职位。真的 A请注意,您选择了不遵循。我认为导致问题的原因是您没有使用位置外键的默认命名。您使用了位置Id而不是位置Id 以下是标准的。由于该标准遵循命名约定,因此不需要fluent API或任何属性
class Position
{
public int Id {get; set;}
// a Position has zero or more Employees:
public virtual ICollection<Employee> Employees {get; set;}
...
}
class Employee
{
public int Id {get; set;}
// every Employee belongs to exactly one Position using foreign key:
public int PositionId {get; set;}
public virtual Position Position {get; set;}
...
}
两者都会起作用。实体框架足够聪明,可以在SQL语句中只使用Position.Id
同样,您可以在一个报表中添加新职位和员工:
Employee Employee1 = myDbContext.Employees.Add(new Employee()
{
Position = new Position() {...}
...
}
或者添加一个新职位,其中包含多个新员工:
Position addedPosition = new Position()
{
Employees = new List<Employee>()
{
new Employee() {...},
new Employee() {...},
new Employee() {...},
}
...
}
positionaddedposition=新位置()
{
雇员=新名单()
{
新员工(){…},
新员工(){…},
新员工(){…},
}
...
}
还有其他一些偏差。它们可能不会造成问题,但如果没有理由,为什么要偏离标准
- 保存您的
的属性未以复数形式命名ICollection
Employees
- 您可以让构造函数创建一个HashSet,它不用于查询
数据库集表示数据库中的一个表。您确定此表有哈希集吗?如果对一个职位及其雇员执行查询,并在调试器中签入雇员集合的实际类,您将看到它不是哈希集。那么为什么要创建一个呢?您需要告诉EF该职位存在。您可以通过将其提取到跟踪中或通过设置其实体状态来实现此目的:
context.Entry(toModel.Position).state=EntityState.Unchanged代码>。由于您似乎正在使用存储库,因此需要进行相应的调整。看,是的,很有效,非常感谢。但我想知道,这个解决方案有多灵活?我必须始终知道,将创建哪个实体,并且哪个实体将只作为FK使用。我认为代码看起来不太好(服务中的方法):public void create(Data.Models.Employee-Employee){dbContext.Entry(Employee.Position).State=System.Data.entity.EntityState.Unchanged;dbContext.Employee.Add(employee);dbContext.SaveChanges();}
你也应该能够通过FK更新它。你可能需要将导航设置为null。如果你想走这条路,还有其他一些关于反射的帖子。还有图书馆。是的,谢谢。我会读这个。再次非常感谢,因为它很好用。但是你的意思是:你应该能够通过FK更新它FK也是?您可以直接设置FK来更新位置,但您需要将导航属性设置为null。请参阅中的“保存并使用外键”。是的,但再次向DB发送查询,因为一条记录无效,并且我已经有Id要添加。毕竟,如果我不告诉EF该记录存在,它仍将创建一条新记录
public Data.Models.Employee ToEmployee(Data.Models.Position position)
{
return new Data.Models.Employee
{
Name = Name,
Surname = Surname,
Phone = Phone,
Salary = Salary.HasValue ? Salary.Value : 0,
Position = position
};
}
class Position
{
public int Id {get; set;}
// a Position has zero or more Employees:
public virtual ICollection<Employee> Employees {get; set;}
...
}
class Employee
{
public int Id {get; set;}
// every Employee belongs to exactly one Position using foreign key:
public int PositionId {get; set;}
public virtual Position Position {get; set;}
...
}
public override void OnModelCreating(...)
{
modelBuilder.Entity<Position>()
// a position has zero or more Employees via property Employees
.HasMany(position => position.Employees)
// every Employee has exactly one Position
.WithRequired(employee => employee.Position)
// using foreign key Position_id
.HasForeignKey(employee => employee.Position_Id);
}
Position existingPosition = ...;
Employee Employee1 = myDbContext.Employees.Add(new Employee()
{
Position = existingPosition;
...
}
Employee Employee2 = myDbContext.Employees.Add(new Employee()
{
PositionId = existingPosition.Id;
...
}
Employee Employee1 = myDbContext.Employees.Add(new Employee()
{
Position = new Position() {...}
...
}
Position addedPosition = new Position()
{
Employees = new List<Employee>()
{
new Employee() {...},
new Employee() {...},
new Employee() {...},
}
...
}