我对Entity Framework有点陌生。我有一个如下定义的类,该类对应于具有由两列组成的复合外键的数据库表:GroupID
和CompanyID
,以及名为RegionID
的第三个外键:>
[Table("GroupMembers")]
public class GroupMember
{
[Key, ForeignKey("GroupID"), Column(Order = 1)]
public int GroupCompanyID { get; set; }
[Key, ForeignKey("CompanyID"), Column(Order = 2)]
public int MemberCompanyID { get; set; }
[Column("MemberCode")]
public string MemberCompanyCode { get; set; }
[Column("RegionID")]
public int RegionId { get; set; }
}
当我拥有MemberCode
和GroupID
的值时,我尝试以下查询来检索MemberCompanyID
:
var GroupMember = await repository.GroupMembers
.FirstOrDefaultAsync(x => x.MemberID == memberId &&
x.CompanyID == manufacturerId);
我收到以下异常:
不能将属性“ GroupID”配置为导航属性。该属性必须是有效的实体类型,并且该属性应具有非抽象的getter和setter。对于集合属性,该类型必须实现ICollection,其中T是有效的实体类型
我认为我在OnModelCreating
方法中丢失了一些内容,我尝试了以下操作,但没有用:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<GroupMember>()
.HasKey(gm => new {gm.GroupID, gm.MemberID});
}
要注意的另一件事是GroupID
和MemberID
都引用相同的主键列,在名为OrganizationID
的表中称为Organizations
,只是不同的值。我不确定这是否会影响任何事情。
有人能指出我正确的方向吗?谢谢!
答案 0 :(得分:1)
该代码有点令人困惑,我不确定该如何编译。 :)我的想法是,您正在寻找更类似的东西:
[Table("GroupMembers")]
public class GroupMember
{
[Key, ForeignKey("Group"), Column(Order = 1)]
public int GroupCompanyID { get; set; }
[Key, ForeignKey("Company"), Column(Order = 2)]
public int MemberCompanyID { get; set; }
[Column("MemberCode")]
public string MemberCompanyCode { get; set; }
[Column("RegionID")]
public int RegionId { get; set; }
public virtual Company Company { get; set; }
public virtual Group Group { get; set; }
}
[Table("Companies")]
public class Company
{
[Key]
public int CompanyID { get; set; }
public string Name { get; set; }
// ...
}
[Table("Groups")]
public class Group
{
[Key]
public int GroupID { get; set; }
// ...
}
导航属性指向相关实体,EF会将它们关联起来,以便您可以加载它们的数据并通过这些属性引用它们。
延迟加载:(注意,这可能意味着会对数据库运行额外的查询)
var groupMember = context.GroupMembers.FirstOrDefault(x => x.RegionId == 4);
var companyName = groupMember.Company.Name; // Context will check if the company is loaded and load it if needed.
急于加载:
var groupMember = context.GroupMembers
.Include(x => x.Company)
.Include(x => x.Group)
.FirstOrDefault(x => x.RegionId == 4);
var companyName = groupMember.Company.Name; // Member's company (and group) already loaded above.
选择地图:(匿名类型示例)
var groupMemberDetails = context.GroupMembers
.Where(x=> x.RegionId == 4)
.Select(x => new
{
x.GroupId,
x.CompanyId,
x.RegionId,
CompanyName = x.Company.Name
}).FirstOrDefault();
Select可用于填充诸如ViewModel或DTO之类的东西,这是利用EF的非常强大的选项,而不会触发延迟的惰性调用。这种方法的优势在于,发送到数据库的查询仅返回填充数据所需的字段,而不是实体和相关导航属性中的所有内容。