2011-10-07 18 views
9

tengo los dos modelos siguientesentidad Código Marco Primera relación uno a uno

public class Account 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int CurrentPeriodId { get; set; } 

    [ForeignKey("CurrentPeriodId")] 
    public virtual Period CurrentPeriod { get; set; } 

    public virtual ICollection<Period> Periods { get; set; } 
} 

public class Period 
{ 
    public int Id { get; set; } 
    public int AccountId { get; set; } 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 

    public virtual Account Account { get; set; } 
} 

y estoy tratando de ejecutar la siguiente consulta:

from p in context.Periods 
where p.AccountId == accountId && 
     p.Id == p.Account.CurrentPeriodId 
select p.StartDate 

y me da una excepción SQL diciendo "no válida nombre de columna Account_AccountId ".

Sé que podría acercarse a esto desde el lado de la cuenta y hacer algo como

from a in context.Accounts 
where a.Id == id 
select a.CurrentPeriod.StartDate 

pero me gustaría saber cómo configurar la relación para obtener la otra consulta para trabajar. ¿Qué me estoy perdiendo?

Respuesta

8

Creo que su implementación es incorrecta. AFAIK, No se puede definir una relación uno a uno usando este enfoque en EF.
Eche un vistazo a su base de datos generada, tiene una columna Account_Id definida en su tabla Periods. Esto es lo que usted tiene que definir:

public class Account 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int CurrentPeriodId { get; set; } 
    public virtual Period CurrentPeriod { get; set; } 
    public virtual ICollection<Period> Periods { get; set; } 
} 

public class Period 
{ 
    public int Id { get; set; } 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 
} 

Entonces, el contexto y inicializador:

public class TestContext : DbContext 
{ 
    public DbSet<Account> Accounts { get; set; } 
    public DbSet<Period> Periods { get; set; } 

static TestContext() 
{ 
    Database.SetInitializer(new DbInitializer()); 
} 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Account>().HasRequired(a => a.CurrentPeriod).WithMany().HasForeignKey(a => a.CurrentPeriodId); 
    } 
} 

class DbInitializer : DropCreateDatabaseAlways<TestContext> 
{ 
    protected override void Seed(TestContext context) 
    { 
     context.Database.ExecuteSqlCommand("ALTER TABLE Accounts ADD CONSTRAINT uc_Period UNIQUE(CurrentPeriodId)"); 
    } 
} 

Para obtener más información acerca de One-a-uno, leen el blog de la serie Mr. Manavi en this address.
actualización:
Basado en su comentario, si usted quiere tener una referencia a Account de Period, se puede poner un atributo ForeignKey en la clave principal de su cuenta.

Un buen ejemplo se encuentra en this address (la parte con el título "Asignar una Uno a Cero o una relación")

+0

Con esta solución He perdido mi referencia a la cuenta del Período sin embargo. –

+0

@Nick Olsen: actualicé mi respuesta. – Kamyar

Cuestiones relacionadas