EF 4.1 RC Code First - 映射到现有数据库&指定外键名称

时间:2011-04-07 10:21:11

标签: ef-code-first entity-framework-4.1 fluent-interface

我有两节课。公司有一个县反对它:

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

我正在尝试映射到现有数据库,其中Company表包含Country记录的外键。所以我可能需要首先告诉代码外键列的名称。

以下是完整的代码示例。基于我尝试的不同的事情,它目前失败了不同的例外。到目前为止,似乎还缺乏有关这方面的内容。

因此,使用Code First Fluent API如何定义外键列的名称?

测试应用

按如下方式创建数据库:     创建数据库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#app:

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 个答案:

答案 0 :(得分:5)

public CompanyConfiguration()
{
    //...
    HasRequired(x => x.HomeCountry).WithMany()
        .Map(x => x.MapKey("HomeCountryId"));
}

答案 1 :(得分:0)

我们正在使用Code First将Web窗体应用程序移动到MVC3,而不会出现任何问题。这里有两个示例模型和我正在使用的DbContext。 prDepartments&amp; prCategories映射到db中的表,ApplicationDBContext与Web.config

中的连接字符串匹配

prCategory中的DeptID字段是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; }
}