EF Code First 4.1 - Как настроить отношение "один ко многим" по умолчанию

У меня есть объект "Клиент", который ссылается на набор адресов. Сложность здесь заключается в том, что я хочу иметь возможность идентифицировать конкретный адрес как адрес по умолчанию.

Если возможно, я хотел бы сохранить FK адреса по умолчанию в таблице клиентов. Это кажется более элегантным, чем наличие столбца в таблице адресов для определения значения по умолчанию.

У меня возникли трудности с беглым API с точки зрения определения этой взаимосвязи. Когда я запускаю следующий код, я получаю исключение, в котором говорится: «Произошла ошибка при сохранении сущностей, которые не раскрывают свойства внешнего ключа для своих отношений. Свойство EntityEntries вернет значение null, потому что отдельная сущность не может быть идентифицирована как источник исключения. Обработку исключений при сохранении можно упростить путем раскрытия свойств внешнего ключа в ваших типах сущностей. Подробнее см. InnerException. " «Невозможно определить допустимый порядок для зависимых операций. Зависимости могут существовать из-за ограничений внешнего ключа, требований модели или значений, сгенерированных хранилищем»

Я создал консольное приложение, чтобы показать точную проблему. В этом тестовом приложении у меня есть объект «Клиент», адрес и конфигурация api flient.

Любая помощь будет принята с благодарностью:

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();
        }
    }
}

Большое спасибо,

Пол.

6
задан Todd 11 March 2012 в 02:18
поделиться