Third Edit: Changed plenty of my code at the end of the question, left the original just in case that was the way to go.
I'm having a problem understanding how to work with multiple one-to-one relationships in EF. I already had made a one-to-one relationship between two models, but when I tried to add another model one-to-one relationship to the mix, things got ugly. Second Edit: I now am working with Composite keys, since there are another relationships in the database that seemed to use them. Still having problems doing the one-to-one relationships, here's the code:
First, I got the one of the parents:
public class CodigoAgrupadorCuentas
{
[Key]
[Column(Order = 0)]
[StringLength(36)]
public string CompanyID { get; set; }
[Key]
[Column(Order = 1)]
[StringLength(36)]
public string DivisionID { get; set; }
[Key]
[Column(Order = 2)]
[StringLength(36)]
public string DepartmentID { get; set; }
[Key]
[Column(Order = 3)]
[Required]
public int CodigoAgrupadorCuentasID { get; set; }
[Required]
public string Code { get; set; }
public virtual CatalogoDeCuentas CatalogoDeCuentas { get; set; }
}
Here's the the child that has two parents:
public class CatalogoDeCuentas
{
public CatalogoDeCuentas()
{ }
[Key]
[Column(Order = 0)]
[StringLength(36)]
public string CompanyID { get; set; }
[Key]
[Column(Order = 1)]
[StringLength(36)]
public string DivisionID { get; set; }
[Key]
[Column(Order = 2)]
[StringLength(36)]
public string DepartmentID { get; set; }
[Key]
[Column(Order = 3)]
[Required]
public int CatalogoDeCuentasID { get; set; }
public string Information { get; set; }
public virtual CodigoAgrupadorCuentas CodigoAgrupadorCuentas { get; set; }
public virtual LedgerChartOfAccount LedgerChartOfAccount { get; set; }
}
}
Second Parent class:
public partial class LedgerChartOfAccount
{
[Key]
[Column(Order = 0)]
[StringLength(36)]
public string CompanyID { get; set; }
[Key]
[Column(Order = 1)]
[StringLength(36)]
public string DivisionID { get; set; }
[Key]
[Column(Order = 2)]
[StringLength(36)]
public string DepartmentID { get; set; }
[Key]
[Column(Order = 3)]
[StringLength(36)]
public string GLAccountNumber { get; set; }
public string description { get; set; }
public virtual CatalogoDeCuentas CatalogoDeCuentas { get; set; }
}
And finally, here's the context:
public class PolizasDBContext: DbContext
{
public PolizasDBContext()
: base("PolizasDBContext")
{
}
public DbSet<CatalogoDeCuentas> TablaCatalogoDeCuentas { get; set; }
public DbSet<CodigoAgrupadorCuentas> TablaCodigoAgrupCuentas { get; set; }
public DbSet<LedgerChartOfAccount> TablaChartAccounts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<LedgerChartOfAccount>()
.HasKey(x => new { x.CompanyID, x.DivisionID, x.DepartmentID, x.GLAccountNumber });
modelBuilder.Entity<CatalogoDeCuentas>()
.HasKey(x => new { x.CatalogoDeCuentasID, x.CompanyID, x.DivisionID, x.DepartmentID });
modelBuilder.Entity<CodigoAgrupadorCuentas>()
.HasKey(x => new { x.CodigoAgrupadorCuentasID, x.CompanyID, x.DivisionID, x.DepartmentID });
modelBuilder.Entity<CatalogoDeCuentas>()
.HasRequired(x => x.CodigoAgrupadorCuentas)
.WithOptional(x => x.CatalogoDeCuentas)
.Map( x => x.MapKey("CompanyID"));
modelBuilder.Entity<CatalogoDeCuentas>()
.HasRequired(x => x.LedgerChartOfAccounts)
.WithOptional(x => x.CatalogoDeCuentas)
.Map(x => x.MapKey("CompanyID"));
base.OnModelCreating(modelBuilder);
}
At this point, I get the next error when I try to scaffold:
In Summary: What would be the way, to keep a one to one relationship between CodigoAgrupadorCuentas and CatalogoDeCuentas, and at the same time have a one to one relationship between LedgerChartOfAccount and Catalogo de Cuentas?
First Edit: Forgot to mention, that GLAccountnumber was suppose to be LedgerChartOfAccounts Key.
Still trying to fix this, and I honestly have no idea why i'm struggling so much, from all the research I have done it should be simple. I have made again plenty of changes to the code above. Here's the changes:
public class CodigoAgrupadorCuentas
{
[Key]
[Required]
public int CodigoAgrupadorCuentasID { get; set; }
[Required]
public string Code { get; set; }
public CatalogoDeCuentas CatalogoDeCuentas { get; set; }
}
Removed the Composite keys from Codigo Agrupador, since from what I read, I don't necessarily need them to make this work. Also removed the virtual keyword virtual from CatalogoDeCuentas, because of an error I had that i'll show at the end. But anyways, I also changed:
public class CatalogoDeCuentas
{
public CatalogoDeCuentas()
{ }
[Key]
[Column(Order = 0)]
[Required]
public int CatalogoDeCuentasID { get; set; }
[Key]
[Column(Order = 1)]
[StringLength(36)]
[Required]
public string GLAccountNumber { get; set; }
public string Information { get; set; }
public CodigoAgrupadorCuentas CodigoAgrupadorCuentas { get; set; }
public LedgerChartOfAccount LedgerChartOfAccount { get; set; }
}
}
Almost same changes, only that in this case, I wanted to link CatalogoDeCuentas and LedgerAccountOfChart with the GLAccountNumber, that's why I added it as a key.
Another big change was on the Context:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<CatalogoDeCuentas>()
.HasRequired(x => x.CodigoAgrupadorCuentas)
.WithOptional(x => x.CatalogoDeCuentas);
modelBuilder.Entity<CatalogoDeCuentas>()
.HasRequired(x => x.LedgerChartOfAccounts)
.WithOptional(x => x.CatalogoDeCuentas);
base.OnModelCreating(modelBuilder);
}
Made it a lot simpler. The only change I did to LedgerChartOfAccounts from the original code posted was removing the virtual word in CatalogoDeCuentas.
Now, when I try to scaffold, I get the next error:
And that's where I am so far... help?
For it to be (One-to-One) LedgerChartOfAccount
should have a primary key of public int CatalogoDeCuentasID {get; set;}
In the model builder your configuration should look like this:
modelBuilder.Entity<LedgerChartOfAccount>()
.HasKey(x => x.CatalogoDeCuentasID);
modelBuilder.Entity<LedgerChartOfAccount>()
.HasRequiredPrincipal(x => x.CatalogoDeCuentas)
.WithRequired(x => x.LedgerChartOfAccount);
For more information check out Configuring Relationships with the Fluent API