Relationship one for many and many for an Entity Framework

Asked

Viewed 1,332 times

2

I am developing these classes of this diagram, but I am in doubt how to declare relationships [One for many, and many for one]

This is the diagram:Diagrama de classes

for example Product has a Category, and a Category has Multiple Products:

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

    [Display (Name = "Descrição")]
    public string Descricao { get; set; }

    [Display (Name = "Preço de Compra")]
    public double PrecoCompra { get; set; }

    [Display (Name = "Preço de Venda")]
    public double PrecoVenda { get; set; }

    public double Desconto { get; set; }
    public string Imagem { get; set; }
    public string Garantia { get; set; }
    public string Fabricante { get; set; }

}

Category

public class Categoria
{
    public int Codigo { get; set; }

    public string Nome { get; set; }
    public double Desconto { get; set; }
}

How do I declare them for EF to understand these relationships?

In this diagram, to declare the class person who has address I made:

    public class Pessoa
{
    [Key]
    public int Codigo { get; set; }
    ...
    public int EnderecoId { get; set; }
    public Endereco Endereco { get; set; }
}

Is that statement correct?

Grateful

  • I’m trying to learn from this: https://msdn.microsoft.com/en-us/library/jj591620(v=vs.113). aspx if I can understand everything, put here dps

2 answers

3

Example of 1xN mapping:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int CurrentGradeId { get; set; }
    public Grade CurrentGrade { get; set; }
}

public class Grade
{
    public int GradeId { get; set; }
    public string GradeName { get; set; }
    public string Section { get; set; }

    public ICollection<Student> Students { get; set; }
}

public class SchoolContext : DbContext
{
    public DbSet<Student> Students { get; set; }
    public DbSet<Grade> Grades { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // configures one-to-many relationship
        modelBuilder.Entity<Student>()
            .HasRequired<Grade>(s => s.CurrentGrade)
            .WithMany(g => g.Students)
            .HasForeignKey<int>(s => s.CurrentGradeId);          }
    }
}

Reference: here

2


You can use the Entityconfig to make this mapping in an elegant and practical way.

It is important to use the Virtual in your relationships, this allows the Entity Framework to create a proxy around the virtual property so that the property can support lazy loading and more efficient change tracking.

I left commented some descriptions.

// virtual ICollection<Products> Products cria uma lista de produtos na categoria ... 
// Virtual permite que o Entity Framework crie um proxy em torno da propriedade virtual 
// para que a propriedade possa suportar //o carregamento preguiçoso e o rastreamento de mudanças mais eficiente. 
public partial class Categories
{
    public Categories()
    {
        Products = new HashSet<Products>();
    }
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
    public string Description { get; set; }
    public byte[] Picture { get; set; }

    public virtual ICollection<Products> Products { get; set; }
}

// virtual Categories Categories { get; set; } Cria um objeto categoria para cada produto.
public partial class Products
{
    public Products()
    {
        this.OrderDetails = new HashSet<OrderDetails>();
    }

    public int ProductID { get; set; }
    public string ProductName { get; set; } 

    public virtual Categories Categories { get; set; }
}

// Configuração usando o code first 
public class CategoriesConfiguration : EntityTypeConfiguration<Categories>
{
    public CategoriesConfiguration()
    {
        HasKey(p => p.CategoryID);
        Property(p => p.CategoryName).HasColumnType("nvarchar").IsRequired().HasMaxLength(15);
        Property(p => p.Description).HasColumnType("ntext").HasMaxLength(400).IsOptional();
        Property(p => p.Picture).HasColumnType("image").IsOptional();

        ToTable("Categories");

        // HasMany declara que categorias tem varios produtos 
        // WithOptional diz que o produto pode ter ou não uma categoria ..
        HasMany(p => p.Products)
            .WithOptional(p => p.Categories);
    }
}
  • then in this example, WithOptional receives a function that expects an object of the type Products and returns one of the type Categories that’s it ?

  • the part about having a public int CategoriesId {get;set;} inside Products to be used Mo FK does not need ? (sorry the questions, I’m trying to understand this...rs.... never worked with EF)

  • 1

    No need, you already have navigation for categories that have your id. // Withoptional says that the product may or may not have a category .. In case you can receive a NULL value

  • 1

    That code is available in git https://github.com/MarconcilioSouza/Projetos/tree/master/Projeto_Modelo

  • It returned one in my mapping: Mloja.Models.Context.Product_category: Multiplicity Conflicts with the referential Constraint in Role 'Product_categoria_target' in Relationship 'Product_category'. Because all of the properties in the Dependent Role are non-nullable, multiplicity of the Principal Role must be '1'.

  • My onmodelBuilder: modelBuilder.Entity<Product>() . Hasoptional(p => p.Category) . Withmany(p => p.Products). Hasforeignkey(p => p.Categoriaid);

  • remove . Hasoptional(p => p.Category)

  • Error here for compiling. modelBuilder.Entity<Product>() . Withmany(p => p.Products). Hasforeignkey(p => p.Categoriaid);

  • Yes... your relationship is M-M between products? Wouldn’t it be . Withmany(p => p.Products) ... . Entity<Category>() .Withmany(p => p.Products)

  • 1

    my relationship is one for many.

  • you are trying to make a Product to Product relation changes the modelBuilder.Entity<Product>() to modelBuilder.Entity<Category>()

Show 6 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.