“NameOfProperty”不能用作实体类型“NameOfType”的属性,因为它被配置为导航

Posted

技术标签:

【中文标题】“NameOfProperty”不能用作实体类型“NameOfType”的属性,因为它被配置为导航【英文标题】:"NameOfProperty" cannot be used as a property on entity type 'NameOfType' because it is configured as a navigation 【发布时间】:2021-12-19 21:19:31 【问题描述】:

我有一个带有船舶和预订导航属性的数据库的预订和船舶类别,

    public class Reservation 
        public Reservation() 
            Ship = new Ship();
        
        public int Id  get; set; 
        public DateTime FromDate  get; set; 
        public DateTime ToDate  get; set; 
       [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public Ship Ship  get; set; 
   

    public class Ship 
        public int Id  get; set; 
        public string Name  get; set; 
        public string Port get; set; 
        public List<Reservation> Reservations  get; set; 
    

DBcontext.cs 文件:

        protected override void OnModelCreating(ModelBuilder modelBuilder) 
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Reservation>().HasOne(r => r.Ship).WithMany(s => s.Reservations);
            modelBuilder.Entity<Reservation>().HasOne(u => u.Person).WithMany(r => r.Reservations);
            modelBuilder.Entity<Ship>().HasMany(res => res.Reservations).WithOne(s => s.Ship);

            //This line generates the error
            modelBuilder.Entity<Reservation>().Property(a => a.Ship).ValueGeneratedNever();
        

        public DbSet<Reservation> Reservations  get; set; 
        public DbSet<Ship> Ships  get; set; 
    

我添加生成错误的这一行和下面的 executeSqlRawAsync 方法的原因是我试图解决这个错误: Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot insert explicit value for identity column in table 'Ships ' 当 IDENTITY_INSERT 设置为 OFF 时。` 我想在数据库中创建一个带有船的预订,但我不能插入一个值。所以我尝试用这个 ValueGeneragtedNever 方法和 executeRawSql 方法修复它,但它给了我标题中的错误。

public async Task CreateReservation(ReservationGetDTO reservationDTO)
        
            await _context.Database.ExecuteSqlRawAsync("SET IDENTITY_INSERT [dbo].[Reservations] ON");
            _context.Reservations.Add(Mapper.Map(reservationDTO, new Reservation()));
            await _context.SaveChangesAsync();
            await _context.Database.ExecuteSqlRawAsync("SET IDENTITY_INSERT [dbo].[Reservations] OFF");
        

任何想法我错过了什么?

【问题讨论】:

【参考方案1】:

这不起作用的另一个原因是我在按下提交按钮后尝试向客户端的导航属性添加值。但您只能在服务器端为导航属性添加值。

【讨论】:

【参考方案2】:

修复预留类,移除 [DatabaseGenerated(DatabaseGeneratedOption.None)] 和构造函数

public class Reservation 
       
        public int Id  get; set; 
        public DateTime FromDate  get; set; 
        public DateTime ToDate  get; set; 

        public int ShipId  get; set; 
        public virtual  Ship Ship  get; set; 
   

    public class Ship 
        public int Id  get; set; 
        public string Name  get; set; 
        public string Port get; set; 
        public virtual  ICollection<Reservation> Reservations  get; set; 
    

并且由于您使用的是 ef core 5+ 从 dbcontext 中删除所有流式 API,因此您不需要它们

并尝试使用此代码添加新项目

public async Task CreateReservation(ReservationGetDTO reservationDTO)
        
           
          _context.Reservations.Add(Mapper.Map(reservationDTO, new Reservation()));
            await _context.SaveChangesAsync();
           
        

【讨论】:

我按照你的建议做了,但我现在又收到了这个错误:Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot insert explicit value for identity column in table 'Ships' when IDENTITY_INSERT is set to OFF. @Rena821 您必须删除旧数据库并进行干净迁移。你仍然有旧的数据库。并从 dbcontext 中删除所有 fluent api 我删除了数据库,经过其他一些修复后它工作得很好。谢谢。 不客气!

以上是关于“NameOfProperty”不能用作实体类型“NameOfType”的属性,因为它被配置为导航的主要内容,如果未能解决你的问题,请参考以下文章

最佳实践? - 数组/字典作为核心数据实体属性 [关闭]

最佳实践? - 数组/字典作为核心数据实体属性 [关闭]

为啥 ref 结构不能用作类型参数?

TS2538:类型“唯一符号”不能用作索引类型

当类型已知时,类型“T”不能用作泛型类型中的类型参数或方法错误

不能将类引用用作非类型模板参数