EF:数据模型中具有导航属性的1:0..1关系的验证错误

时间:2016-11-21 12:51:12

标签: entity-framework ef-code-first ef-code-first-mapping

我有一些预订及其取消的简单数据模型:

[Table("ReservationCreation")]
public class ReservationCreation
{
    [Key()]
    public int ReservationCreationId { get; set; }

    [InverseProperty("ReservationCreation")]
    public virtual ReservationCancellation ReservationCancellation { get; set; }
}

[Table("ReservationCancellation")]
public class ReservationCancellation
{
    [Key()]
    [ForeignKey("ReservationCreation")]
    public int ReservationCancellationId { get; set; }

    [Required]
    [ForeignKey("ReservationCancellationId")]
    [InverseProperty("ReservationCancellation")]
    public virtual ReservationCreation ReservationCreation { get; set; }
}

public class DbContext : System.Data.Entity.DbContext
{
    public DbContext() : base(@"DefaultConnection") { }
    public DbSet<ReservationCancellation> ReservationCancellation { get; set; }
    public DbSet<ReservationCreation> ReservationCreation { get; set; }
}

internal sealed class Configuration : DbMigrationsConfiguration<DbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = true;
    }
}

这是测试的代码。首先创建预订然后取消预订。 当取消记录被保存到数据库中时,抛出异常&#34;需要ReservationCreation字段&#34;。 如何仅根据预订ID创建取消记录,同时定义导航属性?

class Program
{
    static void Main(string[] args)
    {
        int reservationId;

        // create reservation
        using (var db = new DbContext())
        {
            var reservation = 
                db.ReservationCreation.Add(
                    new ReservationCreation());
            db.SaveChanges();
            reservationId = reservation.ReservationCreationId;
        }

        // cancel reservation by its Id
        using (var db = new DbContext())
        {
            var cancellation =
                db.ReservationCancellation.Add(
                    new ReservationCancellation
                    {
                        ReservationCancellationId = reservationId
                    });
            try
            {
                // an exception is thrown
                db.SaveChanges();
            }
            catch(DbEntityValidationException ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
                foreach (var err in ex.EntityValidationErrors.SelectMany(x_ => x_.ValidationErrors))
                    System.Diagnostics.Debug.WriteLine($"!!!ERROR!!! {err.PropertyName}: {err.ErrorMessage}");
            }
        }
    }
}

我没有找到任何方法来修改数据模型注释。如果我从ReservationCreation属性中删除[Required],那么我将无法创建迁移{或使用该数据模型连接到数据库。)

2 个答案:

答案 0 :(得分:1)

您在ReservationCancellation模型中混淆了一切。

ReservationCreation属性中,您指的是主键实体而不是ReservationCreation属性。

试试这个。

[Table("ReservationCancellation")]
public class ReservationCancellation
{
    [Key()]
    public int ReservationCancellationId { get; set; }

    [ForeignKey("ReservationCreation")]
    public int ReservationCreationId { get; set; }

    [Required]
    public virtual ReservationCreation ReservationCreation { get; set;   }
}

更新

由于每次创建只需要取消一次,因此可以使用更简单的模型执行此操作。

[Table("ReservationCreation")]
public class ReservationCreation
{
    [Key()]
    public int ReservationCreationId { get; set; }

    public virtual ReservationCancellation ReservationCancellation { get; set; }
}

[Table("ReservationCancellation")]
public class ReservationCancellation
{
    [Key()]
    public int ReservationCancellationId { get; set; }

    public virtual ReservationCreation ReservationCreation { get; set; }
}

答案 1 :(得分:1)

我遵循了@dknaack的建议,我对这个问题的最终解决方案是这个数据模型:

[Table("ReservationCreation")]
public class ReservationCreation
{
    [Key()]
    public int ReservationCreationId { get; set; }

    [InverseProperty("ReservationCreation")]
    public virtual ReservationCancellation ReservationCancellation { get; set; }
}

[Table("ReservationCancellation")]
public class ReservationCancellation
{
    [Key()]
    [ForeignKey("ReservationCreation")]
    public int ReservationCancellationId { get; set; }

    [ForeignKey("ReservationCancellationId")]
    public virtual ReservationCreation ReservationCreation { get; set; }
}