Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Tntativa de criar uma tabela de Contatos

Olá, estou praticando asp.net com entity fazendo uma rede social. Mas estou com problemas para gerar meu relacionamento entre usuário e contatos. Se alguém puder ajudar agradeço muito! Segue meu código abaixo.

Erro ao tentar gerar a tabela: "Introducing FOREIGN KEY constraint 'FK_dbo.UsuarioContatoes_dbo.Usuarios_UsuarioId' on table 'UsuarioContatoes' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint. See previous errors."

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace LeiaMais.Entidades
{
    public class UsuarioContato
    {
        public int ContatoId { get; set; }
        public virtual Contato Contatos { get; set; }
        public int UsuarioId { get; set; }
        public virtual Usuario Usuario { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace LeiaMais.Entidades
{
    public class Contato
    {
        public int Id { get; set; }
        public int UsuarioId { get; set; }
        public virtual Usuario Usuario { get; set; }
        public IList<UsuarioContato> UsuarioContato { get; set; }


    }
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace LeiaMais.Entidades
{
    public class Usuario
    {
        public int Id { get; set; }

        [Required]
        public string Nome { get; set; }

        [Required, EmailAddress]
        public string Email { get; set; }

        public virtual IList<UsuarioContato> UsuarioContato { get; set; }



    }
}

insira seu código aqui

using LeiaMais.Entidades;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;

namespace LeiaMais.DAO
{
    public class LeiaMaisContext :DbContext
    {
        public DbSet<Usuario> Usuarios { get; set; }

        public DbSet<Livro> Livros { get; set; }

        public DbSet<Categoria> Categorias { get; set; }

        public DbSet<Contato> Contato { get; set; }

        public DbSet<UsuarioContato> UsuarioContatos { get; set; }

        protected override void OnModelCreating(DbModelBuilder builder)
        {
            builder.Entity<Livro>().HasRequired(l => l.Usuario);
            builder.Entity<Livro>().HasRequired(l => l.Categoria);
            builder.Entity<UsuarioContato>().HasKey(uc => new { uc.ContatoId, uc.UsuarioId });
            base.OnModelCreating(builder);
        }


    }
}

insira seu código aqui

namespace LeiaMais.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

    public partial class Contatos : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Contatoes",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        UsuarioId = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.Usuarios", t => t.UsuarioId, cascadeDelete: true)
                .Index(t => t.UsuarioId);

            CreateTable(
                "dbo.UsuarioContatoes",
                c => new
                    {
                        ContatoId = c.Int(nullable: false),
                        UsuarioId = c.Int(nullable: false),
                    })
                .PrimaryKey(t => new { t.ContatoId, t.UsuarioId })
                .ForeignKey("dbo.Contatoes", t => t.ContatoId, cascadeDelete: true)
                .ForeignKey("dbo.Usuarios", t => t.UsuarioId, cascadeDelete: true)
                .Index(t => t.ContatoId)
                .Index(t => t.UsuarioId);

        }

        public override void Down()
        {
            DropForeignKey("dbo.Contatoes", "UsuarioId", "dbo.Usuarios");
            DropForeignKey("dbo.UsuarioContatoes", "UsuarioId", "dbo.Usuarios");
            DropForeignKey("dbo.UsuarioContatoes", "ContatoId", "dbo.Contatoes");
            DropIndex("dbo.UsuarioContatoes", new[] { "UsuarioId" });
            DropIndex("dbo.UsuarioContatoes", new[] { "ContatoId" });
            DropIndex("dbo.Contatoes", new[] { "UsuarioId" });
            DropTable("dbo.UsuarioContatoes");
            DropTable("dbo.Contatoes");
        }
    }
}
4 respostas

Obs: Estou usando a versão 6.1.1 do entity

solução!

No arquivo de Migrations procure pela definição da tabela

Isso acontece com frequencia nos relacionamentos Many to Many por que se, 
por exemplo você Excluir um Usuario, a deletação em cascata iria excluir os Contatos que ele tem, 
e ao excluir os contatos iria excluir o Usuarios ligados a ele e viraria 
um Loop sem fim de exclusões. 

Então é preciso evitar a exclusão em cascata nesses casos.

Há uma forma de desabilitar essa exclusão em geral modificando o modelBuilder conventions mas creio que para você basta mudar a propriedade 
desta tabela e o resto estará resolvido:

CreateTable(
                "dbo.UsuarioContatoes",
                c => new
                    {
                        ContatoId = c.Int(nullable: false),
                        UsuarioId = c.Int(nullable: false),
                    })
                .PrimaryKey(t => new { t.ContatoId, t.UsuarioId })
                .ForeignKey("dbo.Contatoes", t => t.ContatoId, cascadeDelete: true)
                .ForeignKey("dbo.Usuarios", t => t.UsuarioId, cascadeDelete: true)
                .Index(t => t.ContatoId)
                .Index(t => t.UsuarioId);

E mude o cascadeDelete para false:

 .ForeignKey("dbo.Contatoes", t => t.ContatoId, cascadeDelete: false)
                .ForeignKey("dbo.Usuarios", t => t.UsuarioId, cascadeDelete: false)

Ou....

Se quiser a opcao mais genérico terá de usar algo assim:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Contato>()
            .HasOptional<Usuario>(s => s.Usuario)
            .WithMany()
            .WillCascadeOnDelete(false);
    }

Jaqueline, muito obrigado!! Deu certo!! o///