我在实体框架方面遇到以下问题:
无法确定导航表示的关系类型为"列表"的"预订。参与者"。手动配置关系,或使用"[NotMapped]"特性或在中使用"EntityTypeBuilder.Ignore"OnModelCreating"。
这是我的两个类:
public class Booking
{
[Key]
public int Id { get; set; }
[Required]
public Event? Event { get; set; }
public Invoice? Invoice { get; set; }
[Required]
public Participant? TravelApplicant { get; set; }
public List<Participant>? Participants { get; set; }
[Required]
public int NumberOfParticipants
{
get
{
if (Participants != null)
{
if (TravelApplicant != null)
{
if (TravelApplicant.IsTravelApplicantParticipant)
return Participants.Count + 1;
else
return Participants.Count;
}
}
return 0;
}
set
{
if (Participants != null)
{
if (TravelApplicant != null)
{
if (TravelApplicant.IsTravelApplicantParticipant)
NumberOfParticipants = Participants.Count + 1;
else
NumberOfParticipants = Participants.Count;
}
}
}
}
[Required]
public bool CoronaEntryCheckBox { get; set; }
[Required]
public bool AgbCheckBox { get; set; }
[Required]
public bool NewsletterCheckBox { get; set; }
}
public class Participant
{
[Key]
public int Id { get; set; }
[Required]
public Accommodation? Accommodation { get; set; }
[Required]
public Booking? Booking { get; set; }
[Required]
public Gender Gender { get; set; }
public string? Title { get; set; }
[Required]
public string? FirstName { get; set; }
[Required]
public string? LastName { get; set; }
[Required]
public DateTime? Birthday { get; set; }
[Required]
public string? Street { get; set; }
[Required]
public string? HouseNumber { get; set; }
public string? AdditionalAddress { get; set; }
[Required]
public string? ZipCode { get; set; }
[Required]
public string? City { get; set; }
[Required]
public string? Country { get; set; }
[Required]
public string? EMail { get; set; }
[Required]
public string? Phone { get; set; }
[Required]
public bool IsTravelApplicant { get; set; }
[Required]
public bool IsTravelApplicantParticipant { get; set; }
[Required]
public bool Vegetarian { get; set; }
public string? Note { get; set; }
}
我希望你们中的一个人知道解决方案,提前感谢:(
在配置模型时如何定义关系?
从外观上看,您仍然需要让实体框架知道关系是如何链接的。理想情况下,应该为Participant
存储BookingId
,如果将其标记为Required
,则不应为null。
[Required]
public BookingId int {get; set; }
public virtual Booking Booking { get; set; }
我怀疑您实际上希望它在Booking
类中定义如下:
public virtual List<Participant> Participants { get; set; } = new List<Participant>();
然后,在您的数据库上下文中,您的OnModelCreating
覆盖中会有类似的内容:
modelBuilder.Entity<Booking>(entity =>
{
entity.HasMany(x => x.Participants)
});
modelBuilder.Entity<Participant>(entity =>
{
entity.HasOne(x => x.Booking)
.HasForeignKey(k => k.BookingId);
});
您可以在上查看完整的文档https://learn.microsoft.com/en-us/ef/core/modeling/
EF自动链接关系不一定能解决关系,尤其是当它们翻倍时。您看到的问题可能是因为Booking与Particilant(Booking.TravelApparator(有多对一关系,也有一对多关系(Booking.Participants(。
Mike的回答应该会让你分类,告诉EF使用Participant.BookingId链接回来解决预订问题。参与者,同时您还应该在预订时配置TravelApplicantId FK之类的东西来为Travel申请人提供服务。EF基于约定的方法试图根据导航实体的类型而不是属性的名称来查找/使用FK。这导致在大多数问题上,当依赖约定时,多重引用似乎失败了。
我通常不建议这样的结构,因为虽然这意味着TravelApplication将是参与者集合的一部分,但没有办法在数据级别强制执行这一点。例如,如果我有PersonA、PersonB和PersonC的参与者,其中PersonA是申请人,那么没有什么可以阻止我从参与者中删除PersonA(将他们保留为申请人(或将申请人更改为从未添加到参与者中的PersonD。当然,您可以在应用程序级别验证这一点,但在数据级别没有可用的保护。
或者,您可以将其构建为有一个申请人,集合是额外的参与者。这意味着,当需要所有人时,您总是将申请人附加到参与者中,而不会防止申请人被添加到参与者关系中。
相反,我会使用的方法是使用多对多关系表(BookingParticipants(,使用SortOrder或IsApparator标志来识别主要申请人。这确保了主要申请人始终是相关参与者。
使用排序顺序,其中主申请人是最低索引,并且排序顺序具有唯一约束,因此这满足了在DB级别保护关系和申请人的要求。该标志更具可读性,但缺乏在数据级别进行保护的能力,因为可能会有多个参与者被标记为申请人,或者没有参与者标记为申请人。";申请人";可以由实体公开为未映射的属性,从而获取正确的Participant,尽管我建议在处理未映射属性时使用命名约定,以便于识别它们,并确保它们不会出现在EF-Linq表达式中。
尝试以代码优先模式创建关系。
遵循教程:[Configure one to one-Code First][1]