EF 4.1 RC Code First - отображение в существующую базу данных и указание имени внешнего ключа - PullRequest
5 голосов
/ 07 апреля 2011

У меня есть два класса.Компания имеет округ, настроенный против него:

public class Company
{
    public int Id { get; set; }
    public string CompanyName { get; set; }
    public Country HomeCountry { get; set; }
}

public class Country
{
    public int Id { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
}

Я пытаюсь сопоставить существующую базу данных, в которой таблица компании содержит внешний ключ записи о стране.Поэтому мне, вероятно, нужно сначала указать коду имя столбца внешнего ключа.

Ниже приведен полный пример кода.Это в настоящее время терпит неудачу с различными исключениями, основанными на разных вещах, которые я пытаюсь.Похоже, что пока нет единой документации по этому вопросу.

Итак, используя Code First Fluent API, как определить имя столбца внешнего ключа?

Тестовое приложение:

Создать базу данных следующим образом: CREATE DATABASE CodeFirst;GO

Use CodeFirst

create table Companies
(
    Id int identity(1,1) not null,
    HomeCountryId int not null,
    Name varchar(20) not null,
    constraint PK_Companies primary key clustered (Id)
)

create table Countries
(
   Id                    int identity(1,1) not null
,  Code                  varchar(4)        not null                
,  Name                  varchar(20)       not null                
,  constraint PK_Countries primary key clustered (Id)         
)

alter table Companies
  add
     constraint FK_Company_HomeCountry foreign key (HomeCountryId)
        references Countries (Id) on delete no action

Теперь запустите следующее приложение C #:

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

namespace CodeFirstExistingDatabase
{

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

        static void Main(string[] args)
        {

            // Firstly, add a country record, this works fine.
            Country country = new Country();
            country.Code = "UK";
            country.Name = "United Kingdom";

            MyContext myContext = new MyContext(ConnectionString);
            myContext.Countries.Add(country);
            myContext.Entry(country).State = EntityState.Added;
            myContext.SaveChanges();
            Console.WriteLine("Saved Country");

            // Now insert a Company record
            Company company = new Company();
            company.CompanyName = "AccessUK";
            company.HomeCountry = myContext.Countries.First(e => e.Code == "UK");

            myContext.Companies.Add(company);
            myContext.Entry(company).State = EntityState.Added;
            myContext.Entry(country).State = EntityState.Unchanged;
            myContext.SaveChanges();

            Console.WriteLine("Saved Company"); // If I can get here I'd he happy!

        }
    }

    public class MyContext
        : DbContext
    {
        public DbSet<Company> Companies { get; set; }

        public DbSet<Country> Countries { get; set; }

        public MyContext(string connectionString)
            : base(connectionString)
        {
            Database.SetInitializer<MyContext>(null);
            Configuration.LazyLoadingEnabled = false;
            Configuration.ProxyCreationEnabled = false;
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CountryConfiguration());
            modelBuilder.Configurations.Add(new CompanyConfiguration());

            base.OnModelCreating(modelBuilder);
        }
    }

    public class CompanyConfiguration
        : EntityTypeConfiguration<Company>
    {

        public CompanyConfiguration()
            : base()
        {

            HasKey(p => p.Id);
            Property(p => p.Id)
                .HasColumnName("Id")
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
                .IsRequired();
            Property(p => p.CompanyName)
                .HasColumnName("Name")
                .IsRequired();
            ToTable("Companies");
        }

    }

    public class CountryConfiguration
        : EntityTypeConfiguration<Country>
    {

        /// <summary>
        /// Initializes a new instance of the <see cref="CountryConfiguration"/> class.
        /// </summary>
        public CountryConfiguration()
            : base()
        {

            HasKey(p => p.Id);
            Property(p => p.Id)
                .HasColumnName("Id")
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
                .IsRequired();
            Property(p => p.Code)
                .HasColumnName("Code")
                .IsRequired();
            Property(p => p.Name)
                .HasColumnName("Name")
                .IsRequired();

            ToTable("Countries");
        }

    }

    public class Company
    {
        public int Id { get; set; }
        public string CompanyName { get; set; }
        public Country HomeCountry { get; set; }
    }

    public class Country
    {
        public int Id { get; set; }
        public string Code { get; set; }
        public string Name { get; set; }
    }
}

При сохранении страны вышло следующее: неверное имя столбца 'HomeCountry_Id

Любая помощьбыл бы очень признателен !!

Спасибо, Пол.

Ответы [ 2 ]

5 голосов
/ 07 апреля 2011
public CompanyConfiguration()
{
    //...
    HasRequired(x => x.HomeCountry).WithMany()
        .Map(x => x.MapKey("HomeCountryId"));
}
0 голосов
/ 07 апреля 2011

Мы перемещаем приложение Web Forms в MVC3, используя Code First, против существующей базы данных без каких-либо проблем.Вот 2 примера моделей и DbContext, который я использую.prDepartments & prCategories сопоставляются с таблицами в БД, а ApplicationDBContext соответствует строке подключения в Web.config

Поле DeptID в prCategory является внешним ключом для prDepartment - все прекрасно работает

public class prCategory
{
    [Key]
    public int CatgID { get; set; }
    public int DeptID { get; set; }
    [Required(ErrorMessage="Category Description Is Required")]
    [DisplayName("Desc Name")]
    [CssClass("ui-Field-Name")]
    public string Description { get; set; }
    public string Route { get; set; }
    public string OrderBy { get; set; }
    public virtual prDepartment Department { get; set; }
    public virtual List<prProduct> prProducts { get; set; }
}

public class prDepartment
{
    [Key]
    public int DeptID { get; set; }
    [Required(ErrorMessage = "Department Description Is Required")]
    [RequiredMessage("This is the Required Message")]
    public string Description { get; set; }
    public string Route { get; set; }
    public string OrderBy { get; set; }

    public virtual List<prCategory> prCategories { get; set; }
}

    public class ApplicationDbContext : DbContext
{
        public DbSet<prDepartment> prDepartments { get; set; }
        public DbSet<prCategory> prCategories { get; set; }
        public DbSet<prProduct> prProducts { get; set; }
}
...