0

I have an existing database and want to use EF Code First with the Fluent API to map my entities with the tables in the db.

My tables are :

Bank(KeyB, BankName) - KeyB is PrimaryKey

User(KeyU, UserName, KeyB) - KeyU is PrimaryKey, KeyB has a foreign key and can be null.

I have theses entities :

class Bank
{
    public int Id;
    public string Name;
}

class User
{
    public int KeyU;
    public Bank Bank;
}

I don't manage to get my 0 to 1 association working with fluent API. I tried by adding a nullable int property BankId in the User entity (and I would love to be able to avoid that if possible) and Adding the following code to the mapping with no luck :

class UserMap:EntityTypeConfiguration<User>
{
    public UserMap()
    {
        this.HasKey(u => u.KeyU);
        this.Property(u => u.BankId).HasColumnName("KeyB");
        this.HasOptional(u => u.Bank).WithMany().HasForeignKey(u => u.BankId);
    }
}

The Bank property in the User instance is always null.

Do you have any idea about how to achieve this ?

[UPDATE] I have now the following code that still does not work :

    class TestCFContext:DbContext
    {
        public TestCFContext():base(ConnectionString())
        {}
        private static string ConnectionString()
        {return "Data Source=.;Initial Catalog=Test;Integrated Security=SSPI;";}
        public DbSet<User> Users { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new UserMap());
            modelBuilder.Configurations.Add(new BankMap());
        }
    }
    class UserMap:EntityTypeConfiguration<User>
    {
        public UserMap()
        {
            this.HasKey(u => u.Id);
            this.Property(u => u.Id).HasColumnName("KeyU");
            this.HasOptional(u => u.Bank).WithMany().Map(c => c.MapKey("KeyB"));
            this.ToTable("Users");
        }
    }
    class BankMap:EntityTypeConfiguration<Bank>
    {
        public BankMap()
        {
            this.HasKey(b => b.Id);
            this.Property(b => b.Id).HasColumnName("KeyB");
            this.ToTable("Banks");
        }
    }

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

    class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual Bank Bank { get; set; }
    }

       static void Main(string[] args)
        {
            var c = new TestCFContext();
            foreach (var u in c.Users)
            {
                Console.WriteLine(u.Bank.Id);
            }

}

PatriceVB
  • 1,053
  • 1
  • 10
  • 28

1 Answers1

0

The navigation property User.Bank must be virtual and the entity itself must be public, otherwise Entity Framework is unable to link the Bank object. (Technically, it creates a dynamic class inheriting the entity to ensure working navigation properties...)

public class Bank
{
    public int KeyB { get; set; }
    public string BankName { get; set; }
}

public class User
{
    public int KeyU { get; set; }
    public string UserName { get; set; }
    public virtual Bank Bank { get; set; }
}

With these mappings, you should be able to retrieve the Bank (if available).

public class BankMap : EntityTypeConfiguration<Bank>
{
    public BankMap()
    {
        this.HasKey(b => b.KeyB);
    }
}

public class UserMap : EntityTypeConfiguration<User>
{
    public UserMap()
    {
        this.HasKey(u => u.KeyU);
        this.HasOptional(u => u.Bank)
            .WithMany()
            .Map(c => c.MapKey("KeyB"));
    }
}

I've tested it with the current EF version (6.1.2).

Axel Heer
  • 1,863
  • 16
  • 22
  • Thanks for your help but it still does not work. I've updated my question with my current code. I still do not understand what is missing. – PatriceVB Jan 16 '15 at 19:42
  • @PatriceVB the entities must be public. I updated the answer accordingly. – Axel Heer Jan 16 '15 at 20:12
  • Oh gosh, you're right ! Thanks a lot ! I guess it is related to the dynamic proxy created for the lazy loading. – PatriceVB Jan 16 '15 at 20:37