EF Code First 4.1 - Cómo configurar una relación de uno a muchos con @ @ predetermina

Tengo una entidad de Cliente que hace referencia a una colección de Direcciones. La complicación aquí es que quiero poder identificar una dirección particular como la dirección predeterminada.

Si es posible, me gustaría mantener el FK de la dirección predeterminada en la tabla Cliente. Esto parece más elegante que tener una columna en la tabla de direcciones para identificar el valor predeterminado.

Estoy teniendo dificultades con la API fluida en términos de definir esta relación. Cuando ejecuto el siguiente código obtengo una excepción que dice: "Se produjo un error al guardar entidades que no exponen propiedades de clave externa para sus relaciones. La propiedad EntityEntries devolverá un valor nulo porque no se puede identificar una sola entidad como la fuente de la excepción. El manejo de excepciones mientras se guarda puede hacerse más fácil exponiendo propiedades de clave externa en sus tipos de entidad. Consulte InnerException para obtener más detalles ". "No se puede determinar un pedido válido para operaciones dependientes. Pueden existir dependencias debido a restricciones de clave externa, requisitos de modelo o valores generados por la tienda".

Creé una aplicación de consola para mostrar el problema preciso. En esta aplicación de prueba, tengo una entidad de Cliente, una Dirección y la configuración de api de flient.

Cualquier ayuda sería muy apreciada:

using System;
using System.Collections.Generic;
using System.Data.Entity.ModelConfiguration;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;

namespace OneToManyWithDefault
{

    public class Customer
    {
        private ICollection<Address> m_Addresses;

        public Customer()
        {
            Addresses = new List<Address>();
        }

        public int Id { get; set; }
        public string CompanyName { get; set; }
        public virtual ICollection<Address> Addresses
        {
            get
            {
                if (m_Addresses == null)
                {
                    m_Addresses = new List<Address>();
                }
                return m_Addresses;
            }
            set
            {
                m_Addresses = value;
            }
        }
        public Address DefaultAddress { get; set; }
        public int DefaultAddressId { get; set; }

    }

    public class Address
    {
        public int Id { get; set; }
        public string Town { get; set; }
        public Customer Customer { get; set; }
    }

    public class MyContext
        : DbContext
    {
        public DbSet<Customer> Customers { get; set; }

        public MyContext(string connectionString)
            : base(connectionString)
        {

        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CustomerConfiguration());
            modelBuilder.Configurations.Add(new AddressConfiguration());
            base.OnModelCreating(modelBuilder);
        }
    }

    public class CustomerConfiguration
        : EntityTypeConfiguration<Customer>
    {
        public CustomerConfiguration()
            : base()
        {
            HasKey(p => p.Id);
            Property(p => p.Id)
                .HasColumnName("Id")
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
                .IsRequired();
            Property(p => p.CompanyName)
                .HasColumnName("Name")
                .IsRequired();

            // Configure the mapping for the Default Address (this is likely to be wrong!):
            HasRequired(p => p.DefaultAddress).WithMany()
                .Map(x => x.MapKey("DefaultAddressId"))
                .WillCascadeOnDelete(false);
            HasRequired(p => p.DefaultAddress)
                .WithMany()
                .HasForeignKey(x => x.DefaultAddressId);

            ToTable("Customers");
        }
    }

    public class AddressConfiguration
        : EntityTypeConfiguration<Address>
    {
        public AddressConfiguration()
            : base()
        {
            HasKey(p => p.Id);
            Property(p => p.Id)
                .HasColumnName("Id")
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
                .IsRequired();
            Property(p => p.Town)
                .HasColumnName("Town")
                .IsRequired();

            HasRequired(p => p.Customer)
                .WithMany(c => c.Addresses)
                .Map(x => x.MapKey("CustomerId"));

            ToTable("Addresses");
        }
    }

    class Program
    {
        private const string ConnectionString =
            @"Server=.\sql2005;Database=OneToManyWithDefault;integrated security=SSPI;";

        static void Main(string[] args)
        {
            Customer headOffice = new Customer();
            headOffice.CompanyName = "C1";

            Address address = new Address();
            address.Town = "Colchester";
            headOffice.Addresses.Add(address);

            address = new Address();
            address.Town = "Norwich";
            headOffice.Addresses.Add(address);
            headOffice.DefaultAddress = address;

            MyContext context = new MyContext(ConnectionString);
            context.Customers.Add(headOffice);
            context.SaveChanges();

            Console.WriteLine("Done.");
            Console.ReadLine();
        }
    }
}

Muchas gracias

Paul

Respuestas a la pregunta(1)

Su respuesta a la pregunta