2017-01-16 18 views
0

我向MVC 5 Web API项目添加了一个新实体,但无法使用它与我现有的SQL一起工作数据库。我现有的代码使用工作单元工厂和存储库模式从数据库读取和写入,所以我知道代码工作。没有edmx文件,所以我相信代码最初是使用代码编写的。这是我迄今采取的步骤。实体框架6.1.1无法获得新实体与Unity Work of Factory和Repository模式兼容

步骤1)增加了新的实体,以我的实体文件夹 步骤2)更新的DbContext文件 步骤3)更新UnitOfWork.cs文件 步骤4)手动创建的脚本使用步骤 5个新的SQL表)的添加以下代码到我的Web API服务

using (var uow = _unitOfWorkFactory.Create()) 
      { 

//Code to create newentity object 

uow.newEntityRepository.Insert(newentity); 
await uow.SaveChangesAsync(); 
} 

我没有收到错误。插入操作不会将记录添加到数据库。

我已经使用EntityTypeConfiguration创建了一个实体表映射,我使用OnModelCreating Override调用它。

EntityTypeConfiguration

public class NewEntityMap : EntityTypeConfiguration<NewEntity> 
    { 
     public NewEntityMap() : base() 
     { 
      // Primary Key 
      this.HasKey(t => t.Id); 


      // Table & Column Mappings 
      this.ToTable("NewEntity", "dbo"); 
      this.Property(t => t.Id).HasColumnName("Id"); 
      this.Property(t => t.Created).HasColumnName("Created"); 
      this.Property(t => t.OfferId).HasColumnName("OfferId"); 
      this.Property(t => t.MerchantId).HasColumnName("MerchantId"); 
      this.Property(t => t.ConsumerId).HasColumnName("ConsumerId"); 
      this.Property(t => t.SMSMessage).HasColumnName("SMSMessage"); 
      this.Property(t => t.SendSMS).HasColumnName("SendSMS"); 
      this.Property(t => t.EmailMessage).HasColumnName("EmailMessage"); 
      this.Property(t => t.SendEmail).HasColumnName("SendEmail"); 
      this.Property(t => t.Source).HasColumnName("Source"); 
      this.Property(t => t.FromSMSNumber).HasColumnName("FromSMSNumber"); 
     } 
    } 

OnModelCreating

modelBuilder.Configurations.Add(new newEntityMap()); 

我仍然不能得到记录在表更新。

任何想法?提前致谢!

+0

它看起来像基于这个堆栈溢出的问题,实体可以手动映射,而无需进行数据库迁移。 http://stackoverflow.com/questions/20243796/code-first-mapping-entities-to-existing-database-tables –

+0

这篇博客文章甚至没有提到数据库迁移的必要性。 http://cpratt.co/entity-framework-code-first-with-existing-database/ –

回答

1

EF代码优先是非常简单的,所以这应该起作用。如果你没有使用迁移,你基本上只需添加一个新的模型类(匹配你现有的表定义),并将DbSet NewEntities添加到你的DbContext类中,这听起来像你一样。

两件事情,试图通过淘汰过程追踪问题。

  1. 创建一个新的空白控制台应用程序项目进行测试。
static void Main(string[] args) 
{ 
    MainAsync().Wait(); 
    Console.ReadLine(); 
} 

static async Task MainAsync() 
{ 
    /* Here's where we're gonna start troubleshooting */ 
} 
  • 参考的实体项目,并尝试了所有必要的/所需的性质第一实例的实体类。
  • static void Main(string[] args) 
    { 
        MainAsync().Wait(); 
        Console.ReadLine(); 
    } 
    
    static async Task MainAsync() 
    { 
        // Test instantiating the Entity 
        var newEntity = new NewEntity() { propName: value }; 
    } 
    
  • 运行该项目,并确保工程。否则,您的实体存在问题。否则,请继续执行步骤4.

  • 基于步骤2中的代码构建,添加对包含您的DbContext的项目的引用。现在尝试直接使用的DbContext像这样:

  • static void Main(string[] args) 
    { 
        MainAsync().Wait(); 
        Console.ReadLine(); 
    } 
    
    static async Task MainAsync() 
    { 
        // Test instantiating the Entity 
        var newEntity = new NewEntity() { propName: value }; 
    
        // Now, let's test the Entity with the DbContext directly 
        using (var db = new DbContext()) 
        { 
         db.NewEntities.Add(newEntity); 
         await db.SaveChangesAsync(); 
        } 
    } 
    
  • 运行/调试上面的代码。如果失败,您应该从EF返回一个例外。否则,请继续步骤6.
  • 基于步骤4中的代码构建。添加对包含您的存储库的项目的引用。现在,尝试直接使用存储库,像这样:
  • static void Main(string[] args) 
    { 
        MainAsync().Wait(); 
        Console.ReadLine(); 
    } 
    
    static async Task MainAsync() 
    { 
        // Test instantiating the Entity 
        var newEntity = new NewEntity() { propName: value }; 
    
        // Now, let's test the Entity with the DbContext directly 
        using (var db = new DbContext()) 
        { 
         //db.NewEntities.Add(newEntity); 
         //await db.SaveChangesAsync(); 
    
         // Now, let's test the entity with the DbContext and the Repository 
         // Adjust the lines below as needed if you're not using a generic repository and/or if your insert method is called something else 
         var repository = new EntityRepository<NewEntity>(db); 
         repository.Insert(newEntity); 
         // Comment out the line below if your repository internally calls SaveChangesAsync() on the DbContext 
         // If your Repository class doesn't have a SaveChangesAsync method, you'll need to add one to test it 
         await repository.SaveChangesAsync(); 
        } 
    } 
    
  • 如果失败了,你应该得到一个例外,你可以跟踪。否则,请继续执行步骤8.
  • 基于步骤6中的代码,为您的项目添加对包含您的工作单元工厂(如果尚未参考)的引用。现在,尝试使用直接工厂工作的单位,像这样:
  • static void Main(string[] args) 
    { 
        MainAsync().Wait(); 
        Console.ReadLine(); 
    } 
    
    static async Task MainAsync() 
    { 
        // Test instantiating the Entity 
        var newEntity = new NewEntity() { propName: value }; 
    
        // Now, let's test the Entity with the DbContext directly 
        //using (var db = new DbContext()) 
        //{ 
         //db.NewEntities.Add(newEntity); 
         //await db.SaveChangesAsync(); 
    
         // Now, let's test the entity with the DbContext and the Repository 
         // Adjust the lines below as needed if you're not using a generic repository and/or if your insert method is called something else 
         //var repository = new EntityRepository<NewEntity>(db); 
         repository.Insert(newEntity); 
         // Comment out the line below if your repository internally calls SaveChangesAsync() on the DbContext 
         //await repository.SaveChangesAsync(); 
        //} 
    
        // Now, let's test the entity with the UnitOfWork 
        var uow = new UnitOfWork(); 
        uow.NewEntityRepository.Insert(newEntity); 
        await uow.SaveChangesAsync(); 
    } 
    
  • 如果失败了,你应该得到一个例外,你可以跟踪。否则,请继续执行步骤10.
  • 如果以上所有工作都没有依赖注入,那么我说在您的DI容器中注册了组件注册。你需要确保你有一个真正的实例(实现)绑定和注册运行时的接口。
  • 在EF方面,请确保您没有任何外键或虚拟导航属性给其他未正确装饰或未正确填充的实体。另外,请确保您传递给定模型的所有必需属性。如果没有通过测试项目运行它,您的应用程序可能会吞咽某处发生的错误,但您只是没有看到它,但通过上面列出的排除过程,您应该能够找出问题所在。

    一旦找出问题,您可能想重新考虑在Entity Framework之上使用工作单元和存储库模式,因为它们基本上将这两种模式结合在一起。见this post

    祝你好运。

    +0

    这是现在的工作。谢谢你的帮助。我不必使用软件包管理器控制台发出任何迁移命令。我不必使用任何工具将表格反向工程化为实体/模型。我真的必须做的是确保我的实体安装正确。将DbSet条目添加到DBContex文件并确保我的对象将正确的值传递到数据库中。 –

    0

    您是否使用nuget包管理器控制台来生成更新数据库的脚本?

    您是否:

    a)在您的项目中有一个'Migrations'文件夹? b)在你的数据库中有一个'MigrationHistory'表? c)代码中的任何地方是否有'Database.SetInitializer'行?

    这些将是您首先运行代码的指标。来自DbContext的代码可能很有用。

    +0

    我没有使用包管理器控制台来生成更新数据库的脚本。我不确定是否需要这样做,因为我使用数据库脚本手动创建了新表。 –

    +0

    我的主Web项目中有一个Migrations文件夹。它包含一个Configuration.cs文件。我的数据库中有一个dbo.MigrationsHistory表,但里面没有记录。我还将此行添加到我的DbContext文件中。 public DbSet NewEntities {get;组; } –

    +0

    我发现这行代码。 (公共应用程序上下文) :base }' –

    0

    有几件事情:

    你肯定康恩字符串指向你期望的数据库?

    您为NewEntity添加了一个DbSet到DbContext?

    repository.Insert方法的作用是什么?

    uow和存储库是否使用来自工厂的DbContext的相同实例?还是那些都获得不同的上下文的实例? (即IoC设置为不在相同的会话中提供相同的实例或设置。)

    +0

    是的,连接字符串是正确的。我在我的项目中使用与其他服务相同的代码。是的,我确实为NewEntity添加了DbSet。是的,uow和存储库正在使用DbContext的相同实例。 uow和存储库使用所有相同的代码,所以我非常肯定这不是问题。我想我可能不得不使用包管理器控制台让Entity Framework创建数据库并更新模式,但我不确定。 –

    +0

    如果直接在回购的Insert方法中调用SaveChanges,会发生什么?它仍然无能为力吗? 有没有.Commit()你必须打电话? –

    +0

    没有错误,应用程序像所有工作一样。 .Insert调用此方法。 '公共无效插入(T条目) { _context.Set ().Add(item); SaveChangesAsync()调用这个方法'public Task SaveChangesAsync() { return _context.SaveChangesAsync(); }' –