EF6 Code First Relationship between entities

4

I am trying to create a Condominium Data Model in ASP.NET with SQL Server. I stumbled upon the creation of the proprietario(1) relation with fracao(many) .

The error returned is:

  

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.Fracao_dbo.Proprietario_ProprietarioID". The conflict occurred in database "WebCond", table "dbo.Proprietario", column 'ProprietarioID'.

My classes:

[Table("Fracao")]
public class Fracao
{


    [ScaffoldColumn(false)]
    public int FracaoID { get; set; }

    public int? ProprietarioID { get; set; }
    public virtual Proprietario Proprietario { get; set; }

    [Required]
    public int CondominioID { get; set; }
    public virtual Condominio Condominio { get; set; }

    [Required]
    public int ZonaID { get; set; }
    public virtual Zona Zona { get; set; }

    [Required, StringLength(4), Display(Name = "Letra")]
    public string Letra { get; set; }

    [Required, Display(Name = "Área")]
    public decimal Area { get; set; }

    [Required, Display(Name = "Permilagem")]
    public decimal Permilagem { get; set; }

    [Required, StringLength(4), Display(Name = "Piso")]
    public string Piso { get; set; }

    [Required, StringLength(10), Display(Name = "Porta")]
    public string Porta { get; set; }

}

[Table("Proprietario")]
public class Proprietario
{

    [ScaffoldColumn(false)]
    public int ProprietarioID { get; set; }

    [Required, StringLength(255), Display(Name = "Nome")]
    public string Nome { get; set; }

    [Required, StringLength(500), Display(Name = "Morada"), DataType(DataType.MultilineText)]
    public string Morada { get; set; }

    [Required, StringLength(30), Display(Name = "CPostal")]
    public string CPostal { get; set; }

    [Required, StringLength(100), Display(Name = "Localidade")]
    public string Localidade { get; set; }

    [StringLength(10), Display(Name = "Telefone")]
    public string Telefone { get; set; }

    [StringLength(10), Display(Name = "Telemovel")]
    public string Telemovel { get; set; }

    [DataType(DataType.EmailAddress), Display(Name = "Email")]
    public string Email { get; set; }

    [StringLength(10), Display(Name = "Contribuinte")]
    public string Contribuinte { get; set; }

    public virtual ICollection<Fracao> Fracoes { get; set; }
}

I tried to create the entities in the way that I created others and they are fine, but these are not.

It seems to me that the problem is related to cascade delete , and I have to create the appropriate exceptions, but I do not know which ones.

    
asked by anonymous 31.01.2014 / 13:14

2 answers

1

You could try with the following code:

[Table("Fracao")]
    public class Fracao
    {


        [ScaffoldColumn(false)]
        public int FracaoID { get; set; }

        public int? ProprietarioID { get; set; }

        [InverseProperty("ID")]
        [ForeignKey("ProprietarioID")]
        public virtual Proprietario Proprietario { get; set; }

        [Required]
        public int CondominioID { get; set; }
        public virtual Condominio Condominio { get; set; }

        [Required]
        public int ZonaID { get; set; }
        public virtual Zona Zona { get; set; }

        [Required, StringLength(4), Display(Name = "Letra")]
        public string Letra { get; set; }

        [Required, Display(Name = "Área")]
        public decimal Area { get; set; }

        [Required, Display(Name = "Permilagem")]
        public decimal Permilagem { get; set; }

        [Required, StringLength(4), Display(Name = "Piso")]
        public string Piso { get; set; }

        [Required, StringLength(10), Display(Name = "Porta")]
        public string Porta { get; set; }

    }

Because with [ForeignKey("ProprietarioID")] , you speak to the annotation that FK is defined within it.

UPDATE

Errata, I did not mind the fact that your identifier has the same name as the foreign key, so please remove the annotation [InverseProperty("ID")] .

UPDATE 2

With the following code, which I fully replicated on my machine, it worked perfectly, try the same test as a new project:

DbContext class:

public class TesteContext : DbContext
{
    public DbSet<Fracao> Fracoes { get; set; }
    public DbSet<Proprietario> Proprietarios { get; set; }
}

Fraction Class:

[Table("Fracao")]
public class Fracao
{
    [ScaffoldColumn(false)]
    public int FracaoID { get; set; }

    public int? ProprietarioID { get; set; }

    [ForeignKey("ProprietarioID")]
    public virtual Proprietario Proprietario { get; set; }

    [StringLength(4), Display(Name = "Letra")]
    public string Letra { get; set; }

    [Display(Name = "Área")]
    public decimal Area { get; set; }

    [Display(Name = "Permilagem")]
    public decimal Permilagem { get; set; }

    [StringLength(4), Display(Name = "Piso")]
    public string Piso { get; set; }

    [StringLength(10), Display(Name = "Porta")]
    public string Porta { get; set; }

}

Owner's Class:

[Table("Proprietario")]
public class Proprietario
{
    [ScaffoldColumn(false)]
    public int ProprietarioID { get; set; }

    [StringLength(255), Display(Name = "Nome")]
    public string Nome { get; set; }

    [StringLength(500), Display(Name = "Morada"), DataType(DataType.MultilineText)]
    public string Morada { get; set; }

    [StringLength(30), Display(Name = "CPostal")]
    public string CPostal { get; set; }

    [StringLength(100), Display(Name = "Localidade")]
    public string Localidade { get; set; }

    [StringLength(10), Display(Name = "Telefone")]
    public string Telefone { get; set; }

    [StringLength(10), Display(Name = "Telemovel")]
    public string Telemovel { get; set; }

    [DataType(DataType.EmailAddress), Display(Name = "Email")]
    public string Email { get; set; }

    [StringLength(10), Display(Name = "Contribuinte")]
    public string Contribuinte { get; set; }

    public virtual ICollection<Fracao> Fracoes { get; set; }
}

And the codes of a console program:

using (var db = new TesteContext())
{
    // Create and save a new Blog 
    Console.Write("Enter a name for a new Blog: ");
    var name = Console.ReadLine();

    var proprietario = new Proprietario { Email = "oi" };
    proprietario = db.Proprietarios.Add(proprietario);
    db.SaveChanges();

    var fracao = new Fracao { Area = 1, Proprietario = proprietario };
    db.Fracoes.Add(fracao);
    db.SaveChanges();

    // Display all Blogs from the database 
    var query = from b in db.Fracoes
                orderby b.Area
                select b;

    Console.WriteLine("All blogs in the database:");
    foreach (var item in query)
    {
         Console.WriteLine(item.Area);
    }

    Console.WriteLine("Press any key to exit...");
    Console.ReadKey();
}

With this code, you can insert a Fraction and an Owner, making the link correctly, if you want to upgrade, you will have to do the following:

var fracao = new Fracao { Area = 1, Proprietario = null, ProprietarioId = proprietario.ProprietarioId };

Please try again with these codes and comment if you can.

    
31.01.2014 / 15:10
2

In class Proprietario , put a constructor that initializes ICollection<Fracoes> . For example:

public class Proprietario {

   public Proprietario( ) {
      Fracoes = new List<Fracao>( );
   }

   ...

   public virtual ICollection<Fracao> Fracoes { get; set; }

}

This correctly sets the One-To-Many relationship between the models. There is a here in English that explains also.

Update

I created my own Code-first and copied its classes the way they are, with my modification (I did not include Zona or Condominio only). In the end, I had a class like this:

Fraction

[Table( "Fracao" )]
public class Fracao
{
    [ScaffoldColumn( false )]
    public int FracaoID { get; set; }

    public int? ProprietarioID { get; set; }
    public virtual Proprietario Proprietario { get; set; }

    [Required, StringLength( 4 ), Display( Name = "Letra" )]
    public string Letra { get; set; }

    [Required, Display( Name = "Área" )]
    public decimal Area { get; set; }

    [Required, Display( Name = "Permilagem" )]
    public decimal Permilagem { get; set; }

    [Required, StringLength( 4 ), Display( Name = "Piso" )]
    public string Piso { get; set; }

    [Required, StringLength( 10 ), Display( Name = "Porta" )]
    public string Porta { get; set; }
}

Owner

[Table( "Proprietario" )]
public class Proprietario
{
    public Proprietario( )
    {
        Fracoes = new List<Fracao>( );
    }

    [ScaffoldColumn( false )]
    public int ProprietarioID { get; set; }

    [Required, StringLength( 255 ), Display( Name = "Nome" )]
    public string Nome { get; set; }

    [Required, StringLength( 500 ), Display( Name = "Morada" ), DataType( DataType.MultilineText )]
    public string Morada { get; set; }

    [Required, StringLength( 30 ), Display( Name = "CPostal" )]
    public string CPostal { get; set; }

    [Required, StringLength( 100 ), Display( Name = "Localidade" )]
    public string Localidade { get; set; }

    [StringLength( 10 ), Display( Name = "Telefone" )]
    public string Telefone { get; set; }

    [StringLength( 10 ), Display( Name = "Telemovel" )]
    public string Telemovel { get; set; }

    [DataType( DataType.EmailAddress ), Display( Name = "Email" )]
    public string Email { get; set; }

    [StringLength( 10 ), Display( Name = "Contribuinte" )]
    public string Contribuinte { get; set; }

    public virtual ICollection<Fracao> Fracoes { get; set; }
}

And I ended up with tables and columns like this:

    
31.01.2014 / 20:00