2017-01-16 33 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(); }' –