Relationship N for N and One for N with CodeFirst Data Annotations

9

How can I make the N to N and N to N relationships using Data Annotations?

For example:

A sales move has a user, and a user can have multiple moves.

This same sales movement has several products, and each product can be in several movements.

How can I perform this mapping using Data Annotation?

    
asked by anonymous 21.06.2014 / 03:35

2 answers

9

Another proposal

I apologize, but if you had put your entities at least we could simulate, then I did an example that has pretty much the same logic and you can implement in yours that's giving some errors.

1) N for M (many for many) .

Explanation: Where a Book can have multiple Authors and an Author can be in multiple Books.

[Table("Autor")]
public class Autor
{
    public Autor()
    {
        this.Livros = new HashSet<Livro>();
    }

    [Key]
    [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
    public int AutorId { get; set; }

    [Required()]
    [MaxLength(100)]
    public String Nome { get; set; }

    public virtual ICollection<Livro> Livros { get; set; }

}

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

    public Livro()
    {
        this.Autores = new HashSet<Autor>();
    }

    [Key]
    [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
    public int LivroId { get; set; }

    [Required()]
    [MaxLength(100)]
    public String Titulo { get; set; }

    public int TipoId { get; set; }
    [ForeignKey("TipoId")]
    public virtual Tipo Tipo { get;set;}

    public virtual ICollection<Autor> Autores { get; set; }
}

Notice that in this type only a% of% Authors within the Book and% with% of Books within Author are placed, not having to create one more Entity (in this case it will be the relation). In the collections themselves the operations of ICollection (Add) and ICollection (Remove) will be done, in the intermediate table, AuthorBook, where it has the Author and Book keys.

Look how the proposal would look with those templates generated in the bank.

2)1forN(oneformany)

Explanation:WhereaBookhasaTypeandaTypecanhavemultiplebooks

[Table("Tipo")] public class Tipo { [Key] [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)] public int TipoId { get; set; } [Required()] [MaxLength(100)] public string Descricao { get; set; } [ForeignKey("TipoId")] public ICollection<Livro> Livros { get; set; } }

Inside of Book has a TypeId Add field for the Type entity and within Type a Collection of Books, this forces the relationship between these entities.

Proposed Final Model:

Context:

InthisitemwhichistheclassthatinheritsfromRemove,3entities(ForeignKey,DbContextandAutor)havebeenplaced,andinLivro,IforcedasettingintheTiporelationtoIhaveatag,butformeitisessentialformetotellthemodelwhattherelationshipandnameofthetableislikeifyouleavetheFramework>italsogeneratesbutwithitsownnomenclature.

public class Db: DbContext { public Db() :base("Data Source=.\sqlexpress;Initial Catalog=CBOLayout;Persist Security Info=True;User ID=sa;Password=senha") { } public DbSet<Livro> Livro { get; set; } public DbSet<Autor> Autor { get; set; } public DbSet<Tipo> Tipo { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Autor>() .HasMany<Livro>(x=>x.Livros) .WithMany(x => x.Autores) .Map(x => { x.ToTable("AutorLivro"); x.MapLeftKey("AutorId"); x.MapRightKey("LivroId"); }); base.OnModelCreating(modelBuilder); } }

Settings:

  • OnModelCreating : indicates the name of the table that this entity refers to.

  • N : indicates the M of your table

  • [Table("nome_da_tabela")] : can not contain null values, must be filled in.

  • [Key] : field size defined in the database, example: Primary Key .

  • [Required] : indicates the foreign key.

  • [MaxLength] : With this setting you can set the auto increment of that field.

Running Migrations

using System;
using System.Data.Entity.Migrations;

public partial class newBanco : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.Autor",
            c => new
                {
                    AutorId = c.Int(nullable: false, identity: true),
                    Nome = c.String(nullable: false, maxLength: 100),
                })
            .PrimaryKey(t => t.AutorId);

        CreateTable(
            "dbo.Livro",
            c => new
                {
                    LivroId = c.Int(nullable: false, identity: true),
                    Titulo = c.String(nullable: false, maxLength: 100),
                    TipoId = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.LivroId)
            .ForeignKey("dbo.Tipo", t => t.TipoId, cascadeDelete: true)
            .Index(t => t.TipoId);

        CreateTable(
            "dbo.Tipo",
            c => new
                {
                    TipoId = c.Int(nullable: false, identity: true),
                    Descricao = c.String(nullable: false, maxLength: 100),
                })
            .PrimaryKey(t => t.TipoId);

        CreateTable(
            "dbo.AutorLivro",
            c => new
                {
                    AutorId = c.Int(nullable: false),
                    LivroId = c.Int(nullable: false),
                })
            .PrimaryKey(t => new { t.AutorId, t.LivroId })
            .ForeignKey("dbo.Autor", t => t.AutorId, cascadeDelete: true)
            .ForeignKey("dbo.Livro", t => t.LivroId, cascadeDelete: true)
            .Index(t => t.AutorId)
            .Index(t => t.LivroId);

    }

    public override void Down()
    {
        DropForeignKey("dbo.AutorLivro", "LivroId", "dbo.Livro");
        DropForeignKey("dbo.AutorLivro", "AutorId", "dbo.Autor");
        DropForeignKey("dbo.Livro", "TipoId", "dbo.Tipo");
        DropIndex("dbo.AutorLivro", new[] { "LivroId" });
        DropIndex("dbo.AutorLivro", new[] { "AutorId" });
        DropIndex("dbo.Livro", new[] { "TipoId" });
        DropTable("dbo.AutorLivro");
        DropTable("dbo.Tipo");
        DropTable("dbo.Livro");
        DropTable("dbo.Autor");
    }
}

References:

21.06.2014 / 16:10
6

So:

public class Movimentacao
{
    [Key]
    public int MovimentacaoId { get; set; }
    public int ProdutoId { get; set; }
    public int UsuarioId { get; set; }

    public virtual Produto Produto { get; set; }
    public virtual Usuario Usuario { get; set; }
}

public class Usuario
{
    [Key]
    public int UsuarioId { get; set; }

    ...

    public virtual ICollection<Movimentacao> Movimentacoes { get; set; }
}

public class Produto
{
    [Key]
    public int ProdutoId { get; set; }

    ...

    public virtual ICollection<Movimentacao> Movimentacoes { get; set; }
}
    
21.06.2014 / 05:29