boostivan
boostivan

Reputation: 329

EF CodeFirst One-to-One

I find thousands examples for codefirst relations, but i can't do work my sample !

Many errors like this:

The ForeignKeyAttribute on property 'LanguageID' on type 'BL.Objects.User' is not valid. The navigation property 'Language' was not found on the dependent type 'BL.Objects.User'. The Name value should be a valid navigation property name.

and same same same...

I really want to load language association with user. (en, ru, es)

public abstract class BaseUser : FinanceBase<int>, IUser
{      
    [ForeignKey("Language")]
    public int LanguageID { get; set; }

    [ForeignKey("LanguageID")]
    public virtual Language Language { get; private set; }        

}

public class User : BaseUser
{
    public override void GenerateID()
    {
        ...
    }
}

public abstract class BaseLanguage : FinanceBase<int>, ILanguage
{
    #region Implementation of ILanguage

    public string Code { get; set; }
    public string Fullname { get; set; }
    public string ImagePath { get; set; }

    #endregion
}

public class Language : BaseLanguage
{
    public override void GenerateID()
    {

    }
}

public class FinanceDatabaseContext : DbContext
{
    public FinanceDatabaseContext()
    {
        Database.SetInitializer(new FinanceContextInitializer());    
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Language> Languages { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("Users");
            }).HasKey(x => x.ID).HasRequired(x => x.Language).WithMany().HasForeignKey(x => x.LanguageID);

        modelBuilder.Entity<Language>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Languages");
        }).HasKey(x => x.ID);

        base.OnModelCreating(modelBuilder);
    } 
}

public class FinanceContextInitializer : DropCreateDatabaseIfModelChanges<FinanceDatabaseContext>
{
    protected override void Seed(FinanceDatabaseContext context)
    {
        context.Database.ExecuteSqlCommand("ALTER TABLE Users ADD CONSTRAINT uc_Language UNIQUE(LanguageID)");
    }
}

Thanks !

Upvotes: 0

Views: 178

Answers (3)

boostivan
boostivan

Reputation: 329

Solved. My Navigation property Language has private setter

[ForeignKey("LanguageID")]
public virtual Language Language { get; private set; } 

Upvotes: 0

phil soady
phil soady

Reputation: 11358

Add a virtual navigation field to your User table for language if it isnt already there. Ie you have LanguageId and Language in the POCO class User. The alternative is a navigation field in Language Class back to User, ie Public virtual List Users

But lets stick to Users having BOTH virtual navigation property and Foreign Key Id field.

 ... the rest of User.....
    public int LanguageId
// nav relationship
    public virtual Language Language { set; get; }

// Now the FK declaration as you described should work in fluent API...
// Has required NAVIGATION property, its 1 to many and the I have a field for this FK value called X

modelBuilder.Entity<User>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Users");
        }).HasKey(x => x.ID).HasRequired(x => x.Language).WithMany().HasForeignKey(x => x.LanguageID);

Upvotes: 0

user1968030
user1968030

Reputation:

You don't need to use foreign key for LanguageID

    public int LanguageID { get; set; }
    [ForeignKey("LanguageID ")]
    public virtual Language Language { get; private set; }  

Upvotes: 1

Related Questions