2010-08-30 60 views
6

我的实体名称是“联系人”,我的表名是“联系人”。但是,默认的多元化支持使EF4查找名为“联系人”的表。任何人有关于如何关闭多元化支持的想法?实体框架 - CTP4 - 代码优先 - 如何关闭自动复数?

This发布了一些关于多元化支持的细节。但仍然没有给我一个答案。

我在this后看到以下文字。首先,我不知道我需要做出这个改变的物理.tt文件。此外,我希望只在一个应用中关闭此功能,而不是全部关闭。

在T4工具箱中的代码生成器具有 的多元化在Visual Studio 2010中如果需要 产生DAL没有 多元化,也许 兼容性原因默认开启 ,你可以把 这个选项通过在 generator.Run()方法被调用之前将 以下行添加到.tt文件中。

C#
generator.Pluralize = false;

VB
generator.Pluralize =假

***** UPDATE *****

以下是我使用的代码,我得到如下错误: -

联系

public class Contact 
{ 
public int ContactID { get; set; } 
public string FirstName { get; set; } 
public string LastName { get; set; } 
public string Title { get; set; } 
public DateTime AddDate { get; set; } 
public DateTime ModifiedDate { get; set; } 
} 

语境: -

public class AddressBook : DbContext 
{ 
public DbSet<Contact> Contact { get; set; } 

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Contact>().MapSingleType().ToTable("dbo.Contact"); 
} 

}

主要程序: -

using (var context = new AddressBook()) 
    { 
    var contact = new Contact 
    { 
    ContactID = 10000, 
    FirstName = "Brian", 
    LastName = "Lara", 
    ModifiedDate = DateTime.Now, 
    AddDate = DateTime.Now, 
    Title = "Mr." 

    }; 
    context.Contact.Add(contact); 
    int result = context.SaveChanges(); 
    Console.WriteLine("Result :- " + result.ToString()); 

    } 

而且我得到以下错误 “context.Contact.Add(接触);” -

系统.InvalidOperationException:自创建数据库 以来,支持“AddressBook” 上下文的 模型已更改。手动删除/更新数据库 ,或使用 IDatabaseInitializer实例调用 Database.SetInitializer。例如,对于 示例, RecreateDatabaseIfModelChanges 策略将自动删除,并且 重新创建数据库,并可选择 为其添加新数据。在 System.Data.Entity.Infrastructure.CreateDatabaseOnlyIfNotExists 1.InitializeDatabase(TContext context) at System.Data.Entity.Infrastructure.Database.Initialize() at System.Data.Entity.Internal.InternalContext.Initialize() at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) at System.Data.Entity.Internal.Linq.EfInternalQuery 1.Initialize() 在 System.Data.Entity.DbSet 1.ActOnSet(Action action,EntityState newState, TEntity entity) at System.Data.Entity.DbSet 1.增加(TEntity 实体)在 CodeFirst.Client.Program.Main(字符串[] args)在E:\ Ashish \ Research \ VS Solutions \ EntityFramework \ CodeFirstApproach_EF_CTP4 \ CodeFirst.Client \ Program。CS:line 35

我确信我在某个地方犯了一个愚蠢的错误,只是无法弄清楚。有人可以提供一些指导吗?

ANSWER 随着Pault的帮助下,我描述这个问题和解决方案here

+1

..作为一个便笺:在我看来,保持表名的复数是一种很好的做法。它们代表一组条目,而不是一个条目。 – 2010-09-05 19:52:13

+0

+1 Arve,我同意。但是,您可以了解我无法更改现有数据库中的表名称。 – 2010-09-06 06:07:42

回答

6

因为我对问题的理解发生了变化,所以我添加了第三个答案...对我来说很糟糕吗? ;)

就像我在我的评论中说的,我仍然在学习,我还没有尝试过使用现有的数据库。也就是说,希望其中一个将有所帮助:

斯科特格思里提到的帖子(http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx)有一个杰夫评论说,这可以帮助(我建议阅读完整的评论,因为他更详细地解释) :

Database.SetInitializer<AddressBook>(null); //AddressBook being the context 

我也正好在由罗恩·米勒这个帖子(http://blogs.msdn.com/b/adonet/archive/2010/07/14/ctp4announcement.aspx?PageIndex=2)在最近的过去下方的评论。他建议这可能是一个选择:

public class ProductContext : DbContext 
{ 
    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     modelBuilder.IncludeMetadataInDatabase = false; 
    } 
    ... 
} 

希望其中一个让你走上正轨。

+0

正确的轨道!!! Database.SetInitializer (null)是要走的路。我需要将其作为我程序中的第一行。谢谢! :-)然而,我读过那篇文章,但没有看到评论。获得的经验: - 在一篇出色的博客文章中阅读评论是一件有用的事情。 – 2010-09-07 06:53:38

+0

我想知道Scot如何运行样本中的样本,他在http://weblogs.asp.net/scottgu/archive/2010/07/23/entity-framework-4-code-first-custom-database -schema-mapping.aspx他与现有数据库一起工作并映射到不同的表(tblDinners而不是Dinners)。 – 2010-09-07 07:38:45

+0

我在这里描述了这个问题和解决方案: - http://ashishrocks.spaces.live.com/blog/cns!BED6CE34F24CB429!540.entry – 2010-09-07 08:55:45

2

你只是试图定位一个特定的表名吗?

如果是这样,这可能是你正在寻找的答案:

public class FooDataContext : DbContext 
{ 
    public DbSet<Contact> Contacts { get; set; } 
} 

    protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Contact>().MapSingleType().ToTable("Contact"); 
    } 
} 

这是否帮助还是我完全错过了点?

+0

谢谢你的时间。是的,我试图将一个特定的表名称(在这种情况下不是复数形式)。我使用了非常类似的代码,如您所建议的,并且出现错误。看到我更新的问题。 – 2010-09-06 06:08:26

0

开箱即用,代码优先的东西不会修改或删除现有的数据库。我猜你有一个现有的数据库,你可以手动创建,也可以通过先前运行你的程序创建的框架,然后你改变你的Contact类。一次修复此错误的最快方法是手动删除数据库,或更新它以匹配您的模型。

但是,代码优先功能集的真正威力在于允许快速域创建和重构,而无需担心在开发早期创建和维护数据库脚本。为了做到这一点,我个人认为每次修改模型时允许框架为我删除我的数据库是有用的。当然,这也意味着我想用测试数据为数据库播种。

这里是你如何能做到这一点:

public class MyCustomDataContextInitializer : RecreateDatabaseIfModelChanges<MyCustomDataContext> //In your case AddressBook 
{ 
    protected override void Seed(MyCustomDataContext context) 
    { 
     var contact = new Contact 
     { 
      ContactID = 10000, 
      FirstName = "Brian", 
      LastName = "Lara", 
      ModifiedDate = DateTime.Now, 
      AddDate = DateTime.Now, 
      Title = "Mr." 
     }; 
     context.Contact.Add(contact); 
     context.SaveChanges(); 
    } 
} 

然后,你需要注册这个初始化(发言权的Application_Start(),如果它是一个Web应用程序):

Database.SetInitializer(new MyCustomDataContextInitializer()); 

请注意,您需要:

using System.Data.Entity.Infrastructure; 

这有帮助吗?

+0

Paul,我有一个现有的数据库,我正在设计一个对象模型。所以,首先我创建了我的POCO,并想到先使用代码并打开这面墙。在这种情况下,代码优先不是最好的方式吗?如果是的话,为什么我得到这个错误?如果不是,在这种情况下最好的方法是什么? – 2010-09-06 17:36:54

+0

那么,我仍然自己学习这些东西,所以我不完全确定使用现有数据库的细节。也就是说,Scott Gu有一篇关于这件事的博客文章:http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database。 aspx – ptrandem 2010-09-07 01:51:04

4
protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>(); 
     base.OnModelCreating(modelBuilder); 
    } 
0
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<PluralizingEntitySetNameConvention>(); 
    }