我使用的是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 int Position_Id { get; set; }
public decimal Salary { get; set; }
public virtual Position Position { get; set; }
和
[Table("Position")]
public partial class Position
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Position()
{
Employee = new HashSet<Employee>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Employee> Employee { get; set; }
}
在位置我已经有物品,我让他们下拉。我想要做的就是使用Position的项目创建Employee的新记录,我从下拉列表中获取该ID。我不想创建新职位。我试过这个:
PositionId是一个属性,ToEmployee()是viewModel
中的方法public Data.Models.Employee ToEmployee()
{
return new Data.Models.Employee
{
Name = Name,
Surname = Surname,
Phone = Phone,
Salary = Salary.HasValue ? Salary.Value : 0,
Position = new Data.Models.Position { Id = PositionId }
};
}
在控制器中添加:
var toModel = viewModel.ToEmployee();
_employeeService.Create(toModel);
但是这创造了新员工和新职位,但我希望只有新的Empoloyee以及员工和职位之间的关系。如何在EF中完成?
当我在ToEmployee()中尝试此操作时:
Position_Id = PositionId
返回错误InvalidColumn。
感谢您的帮助!
答案 0 :(得分:1)
显然,职位有零个或多个员工,每个员工只属于一个职位。一个真实的one-to-many relation.。
请注意,您选择不遵循entity framework naming conventions。我认为导致问题的一个原因是你没有使用Position的外键的默认命名。您使用Position_Id而不是PositionId。
以下是标准的。由于此标准遵循命名约定,因此不需要流畅的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;}
...
}
如果您确实有充分的理由为外键使用不同的标识符,则必须告诉实体框架哪个标识符包含外键。这是在DbContext.OnModelCreating
中完成的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);
}
现在,只要您拥有有效PositionId的现有职位,并且想要添加具有此职位的员工,您就可以选择填写PositionId或职位:
Position existingPosition = ...;
Employee Employee1 = myDbContext.Employees.Add(new Employee()
{
Position = existingPosition;
...
}
Employee Employee2 = myDbContext.Employees.Add(new Employee()
{
PositionId = existingPosition.Id;
...
}
两者都有效。实体框架非常智能,只能在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() {...},
}
...
}
还有其他一些偏差。它们可能不会引起问题,但如果没有理由,为什么会偏离标准?
ICollection<Employee>
的属性未以复数Employees
命名。DbSet代表数据库中的表。你确定这个表有一个HashSet吗?如果您使用Employees对Position进行查询,并在调试器中检查Employee集合的实际类,您将看到它不是HashSet。那么为什么要创建一个?
答案 1 :(得分:0)
在DB中查找Position对象并将其传递给ToEmployee()方法
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
};
}