0

I have the below DbContext, Model and Controller (database first). These are referents for two tables (operador and operador2), that complement each other. I mapped these models (table "operador") with (some table) successfuly, but the mapping reference for (table "operador") and (table "operador2") not works fine. I think I have less anything for this it work correctly. (Below the code and a image when the controller has executed.) I need a relationship between and through properties "OpedradorId" and "Operador2Id". Somebody can help me?

/**** DbContext ****/
public class OperadorContext : DbContext
{
    public OperadorContext() : base("name=CnxEasyLabWeb") { }

    public DbSet<OperadorModel> DbOperador { get; set; }
    public DbSet<OpCadastros1Model> DbCadastro { get; set; }
    public DbSet<OpCadastros2Model> DbCadastro2 { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<OperadorModel>().HasKey(o => o.OperadorId);

        modelBuilder.Entity<OpCadastros1Model>().HasKey(c => c.OperadorId);

        modelBuilder.Entity<OpCadastros1Model>()
            .HasRequired(c => c.Operador)
            .WithRequiredPrincipal(o => o.OpCadastros1);

        modelBuilder.Entity<OpCadastros1Model>()
            .HasRequired(c => c.OpCadastros2)
            .WithRequiredDependent(d => d.OpCadastro1);

        modelBuilder.Entity<OperadorModel>().ToTable("operador", "public");
        modelBuilder.Entity<OpCadastros1Model>().ToTable("operador", "public");
        modelBuilder.Entity<OpCadastros2Model>().ToTable("operador2", "public");
    }
}

/**** Models ****/
 public class OpCadastros1Model //: OpGeralModel
{
    [Key, Column("id")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OperadorId { get; set; }

    public virtual OperadorModel Operador { get; set; }

    public virtual OpCadastros2Model OpCadastros2 { get; set; }
}

public class OpCadastros2Model
{
    [Key, Column("operador_id")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OperadorId { get; set; }

    public virtual OpCadastros1Model OpCadastro1 { get; set; }
}

public class OperadorModel
{
    [Key, Column("id")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OperadorId { get; set; }

    public virtual OpCadastros1Model OpCadastros1 { get; set; }

    [Column("nome")]
    [Required]
    public string Login { get; set; }
}

/**** Controller ****/
[HttpPost]
//[Authorize]
[ValidateAntiForgeryToken]
public ContentResult SalvarCadastros(OpCadastros1Model model)
{
    if (ModelState.IsValid)
    {
        #region Update
        if (model.OperadorId > 0)
        {
            var update = _db.DbCadastro.Single(op => op.OperadorId == model.OperadorId);
            _db.Entry(update).CurrentValues.SetValues(model);
            _db.Entry(update).State = EntityState.Modified;         
        }
        #endregion

        #region New
        else
        {
            _db.DbCadastro.Add(model);
        }
        #endregion

        _db.SaveChanges();
    }
    else
    { ... }

    ...
}

The image model passed to controller get null for OpCadastro2

Complementary, I receive this error:

The property 'Operador2Id' is part of the object's key information and can not be modified.

GustavoAdolfo
  • 361
  • 1
  • 9
  • 23
  • Well, I have implemented a workaround provisionally, but I think this is not the ideal solution ( but it worked! ): `var update = _db.DbCadastro.Single(op => op.OperadorId == model.OperadorId);` `_db.Entry(update).CurrentValues.SetValues(model);` `_db.Entry(update).State = EntityState.Modified;` `var update2 = _db.DbCadastro2.Single(op => op.Operador2Id == update.OperadorId);` `if (model.OpCadastros2.Operador2Id == 0) model.OpCadastros2.Operador2Id = model.OperadorId;` `_db.Entry(update2).CurrentValues.SetValues(model.OpCadastros2);` `_db.Entry(update2).State = EntityState.Modified;` – GustavoAdolfo Sep 02 '13 at 19:59
  • Mapping two entities to the same table is common and is called table splitting. See http://weblogs.asp.net/ricardoperes/archive/2013/08/28/entity-framework-code-first-table-splitting.aspx. – Ricardo Peres Sep 03 '13 at 03:47
  • @GertArnold, the problem is with the object inside the , this is always sent "void" to the controller (sent null). – GustavoAdolfo Sep 03 '13 at 12:40
  • @RicardoPeres, the mapping for same tables works fine. The relationship for [Table1].[Split_X] and [Table2].[Split_X] is the problem. – GustavoAdolfo Sep 03 '13 at 12:43

1 Answers1

0

You must have a class that is the primary and other that is the detail. On the primary, declare everything normally:

public class Operador
{
    [Key, Column("id")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OperadorId { get; set; }
    public virtual OpCadastros1Model OpCadastros1 { get; set; }
}

On the secondary, do this:

public class OpCadastros1Model 
{
    [Key, Column("id"), ForeignKey("Operador")]
    public int OperadorId { get; set; }
    [Required]
    public Operador Operador { get; set; }
}

This means that the primary has an optional relationship with the detail and the detail has a required relationship with the primary and gets its primary key from it.

Ricardo Peres
  • 13,724
  • 5
  • 57
  • 74
  • Thank you @RicadoPeres. The relation for [Operador] <--> [OpCadastros1] is ok. The dificult is on relation between [OpCadastros1] (table A) with [OpCadastros2] (table B). – GustavoAdolfo Sep 03 '13 at 12:46
  • Well, it's exactly what I wrote, just change the class names. In a nutshell: on your secondary class, you cannot use identity and you must configure the primary key to be the same column name as the primary of the main class and to also be a foreign key. – Ricardo Peres Sep 03 '13 at 13:24
  • (1) I understand you, but I think I not have explained the question appropriately because the relationship between Operador and OpCadastro1 (the some table) not is the problem. The code is very large to post here. Has two giant tables splitted. My dificult is make a relation between from and from . – GustavoAdolfo Sep 03 '13 at 14:33
  • (2) The has five splits - the principal and de four dependents; the , secondary, has correspondent five splits - the principal and four others. The tables are part from a old desktop system and I not can remodel it. So, I make various web forms for manipulate these datas with ajax and various controllers.
    – GustavoAdolfo Sep 03 '13 at 14:36