我试图在 OnModelCreating() 方法下的 EF-Core 内的两个实体之间建立一对一关系,即 1Hotel-to-1Address,但在 Line#6 .HasForeignKey(... ) 说明:
error CS1660: Cannot convert lambda expression to type 'string' because it is not a delegate type.
1 // One-to-One relationship between Hotel and Address entities.
2 modelBuilder.Entity<Hotel>(entity =>
3 {
4 entity.HasOne(a => a.Address)
5 .WithOne()
6 .HasForeignKey(fk => fk.HotelId)
7 .OnDelete(DeleteBehavior.NoAction)
8 .HasConstraintName("FK_Hotel_Address");
9 });
虽然当我与另一个实体建立一对多关系时同样可以正常工作,但超级实体在两者中都很常见。
11 // One-to-Many relationship between Hotel and Contact entities.
12 modelBuilder.Entity<Hotel>(entity =>
13 {
14 entity.HasMany(c => c.Contacts)
15 .WithOne()
16 .HasForeignKey(fk => fk.HotelId)
17 .OnDelete(DeleteBehavior.NoAction)
18 .HasConstraintName("FK_Hotel_Contacts");
19 });
我的域实体如下所示:
public class BaseEntity
{
public Guid Id { get; set; } = Guid.NewGuid();
public bool IsActive { get; set; } = true;
public DateTime Created { get; set; } = DateTime.UtcNow;
public DateTime Updated { get; set; } = DateTime.UtcNow;
public Guid? UpdatedByUserId { get; set; }
}
public class Hotel : BaseEntity
{
// Initialising navigation properties in constructor
public Hotel()
{
Contacts = new HashSet<Contact>();
}
public required string Name { get; set; }
public string? Title { get; set; }
public bool HasRestaurant { get; set; } = false;
// Foreign Keys
// Navigations Properties
public ICollection<Contact> Contacts { get; set; }
public Address? Address { get; set; }
}
public class Contact : BaseEntity
{
public string? Label { get; set; }
[RegularExpression(@"[+][0-9]", ErrorMessage = "Invalid contact number. Please use numeric values without empty spaces.")]
[MaxLength(15, ErrorMessage = "Upto 15 characters allowed.")]
public required string Number { get; set; }
// Foreign Keys
public Guid? HotelId { get; set; }
public Guid? RestaurantId { get; set; }
}
public class Address : BaseEntity
{
[MaxLength(100, ErrorMessage = "Max limit reached.")]
public required string Line1 { get; set; }
[MaxLength(100, ErrorMessage = "Max limit reached.")]
public string? Line2 { get; set; }
[MaxLength(100, ErrorMessage = "Max limit reached.")]
public required string City { get; set; }
[MaxLength(100, ErrorMessage = "Max limit reached.")]
public required string State { get; set; }
[MaxLength(100, ErrorMessage = "Max limit reached.")]
public required string Country { get; set; }
[RegularExpression(@"[0-9]", ErrorMessage = "Only numeric characters allowed.")]
[MaxLength(10, ErrorMessage = "Max limit reached.")]
public required string ZipCode { get; set; }
// Foreign keys
public Guid? HotelId { get; set; }
public Guid? RestaurantId { get; set; }
}
没有找到 Microsoft 或其他人提供的可以解释此错误的官方链接以及可以解决此问题的解决方法。
这是因为在 Hotel 和 Address 之间的一对一关系中,您需要显式指定哪个实体包含外键,因为它可能是任一侧。
此外,您的地址实体缺少酒店的导航属性。
所以,我们先纠正一下:
public class Address : BaseEntity
{
[MaxLength(100, ErrorMessage = "Max limit reached.")]
public required string Line1 { get; set; }
[MaxLength(100, ErrorMessage = "Max limit reached.")]
public string? Line2 { get; set; }
[MaxLength(100, ErrorMessage = "Max limit reached.")]
public required string City { get; set; }
[MaxLength(100, ErrorMessage = "Max limit reached.")]
public required string State { get; set; }
[MaxLength(100, ErrorMessage = "Max limit reached.")]
public required string Country { get; set; }
[RegularExpression(@"[0-9]", ErrorMessage = "Only numeric characters allowed.")]
[MaxLength(10, ErrorMessage = "Max limit reached.")]
public required string ZipCode { get; set; }
// Foreign keys
public Guid? HotelId { get; set; }
public Guid? RestaurantId { get; set; }
// Navigation Properties
public Hotel? Hotel { get; set; } <-- Add this navigation property******
}
然后在 OnModelCreating() 中,指定您要配置的类型,以显式告诉 EF Core 哪个实体拥有 FK。请注意,我将以速记形式编写此内容,并且也会丢失大括号:
modelBuilder.Entity<Hotel>()
.HasOne(x => x.Address)
.WithOne(x => x.Hotel)
.HasForeignKey<Address>(x => x.HotelId)
.OnDelete(DeleteBehavior.NoAction);
注意,您不需要为 Hotel 和 Contacts 之间的关系进行相同的配置,因为这是一对多关系,因此很明显 FK 位于“多”实体上:
modelBuilder.Entity<Hotel>()
.HasMany(x => x.Contacts)
.WithOne(x => x.Hotel)
.HasForeignKey(x => x.HotelId)
.OnDelete(DeleteBehavior.NoAction);