2014-02-20 92 views
7

我有以下模型 - 第一個(它叫做什麼?)我已經制作的圖。我使用T4來生成類。實體框架問題 - 爲我的表名添加「1」?

enter image description here

現在,我已經導致實體框架以某種方式追加了「1」到DatabaseSupporter實體的表名的問題。數據庫是從這個模型生成的,沒有任何修改。

我試圖執行以下行:

_entities.DatabaseSupporters.SingleOrDefault(s => s.Id == myId); 

執行該線(具有低於其內部異常一起)時,收到的錯誤是:

類型的異常' System.Data.Entity.Core.EntityCommandExecutionException'發生在 mscorlib.dll中,但未在用戶代碼中處理。

無效的對象名稱'dbo.DatabaseSupporter1'。

我試着用下面的Fluent API代碼解決了這個問題(注意函數中的第二行顯式地給「DatabaseSupporter」命名錶),但沒有運氣。

protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder) 
{ 

    modelBuilder 
     .Entity<DatabaseSupporter>() 
     .HasOptional(f => f.DatabaseChatSession) 
     .WithOptionalPrincipal(s => s.DatabaseSupporter); 

    modelBuilder 
     .Entity<DatabaseSupporter>() 
     .Map(m => 
     { 
      m.Property(s => s.Id) 
       .HasColumnName("Id"); 
      m.ToTable("DatabaseSupporter"); 
     }); 

    modelBuilder 
     .Entity<DatabaseSupporter>() 
     .HasMany(s => s.DatabaseGroups) 
     .WithMany(g => g.DatabaseSupporters) 
     .Map(m => 
     { 
      m.ToTable("DatabaseSupporterDatabaseGroup"); 
      m.MapLeftKey("DatabaseGroups_Id"); 
      m.MapRightKey("DatabaseSupporters_Id"); 
     }); 

    modelBuilder 
     .Entity<DatabaseGroup>() 
     .HasRequired(g => g.DatabaseChatProgram) 
     .WithMany(c => c.DatabaseGroups); 

    modelBuilder 
     .Entity<DatabaseGroup>() 
     .HasRequired(g => g.DatabaseOwner) 
     .WithMany(o => o.DatabaseGroups); 

    modelBuilder 
     .Entity<DatabaseOwner>() 
     .HasMany(o => o.DatabaseChatSessions) 
     .WithRequired(o => o.DatabaseOwner); 

    base.OnModelCreating(modelBuilder); 
} 

應當提及的是,Id屬性每個實體實際上是一個Guid

我正在使用Entity Framework 6.0.2。

任何想法?

編輯1 下面是一個包含我的DatabaseSupporter實體在意見中的要求生成的DatabaseSupporter.cs文件。

//------------------------------------------------------------------------------ 
// <auto-generated> 
//  This code was generated from a template. 
// 
//  Manual changes to this file may cause unexpected behavior in your application. 
//  Manual changes to this file will be overwritten if the code is regenerated. 
// </auto-generated> 
//------------------------------------------------------------------------------ 

namespace Coengage.Data.Entities 
{ 
    using System; 
    using System.Collections.Generic; 

    public partial class DatabaseSupporter 
    { 
     public DatabaseSupporter() 
     { 
      this.DatabaseGroups = new HashSet<DatabaseGroup>(); 
     } 

     public bool IsActive { get; set; } 
     public string Username { get; set; } 
     public System.Guid Id { get; set; } 

     public virtual DatabaseChatSession DatabaseChatSession { get; set; } 
     public virtual ICollection<DatabaseGroup> DatabaseGroups { get; set; } 
    } 
} 

編輯2 的錯誤開始發生的歷史後,我加入DatabaseSupporterDatabaseGroup之間的許多一對多鏈接。在該鏈接之前,Fluent代碼也不需要。

+0

我之前沒有使用'T4'來生成任何類,因爲我創建了所有的類,然後讓實體框架創建數據庫(代碼優先)。你可以發佈你的'POCO'類還是'T4'後面的方法?嘗試使用流利的API來更改表名稱將不會像其錯誤的類那樣工作。 – Heberda

+0

我正在使用默認的T4模板。實體框架爲我生成類,但它使用T4。關鍵是雖然T4模板沒有被修改過。 –

+0

它創建了一個可以查看/發佈的POCO類嗎? – Heberda

回答

2

我沒有在這裏有我的開發環境在我的面前,但是我是直接的想法是:

FIRST

你流利看起來不錯 - 但在你的ID複數s列正確嗎?表名上沒有複數形式?這將是公約的反面。

第二

EF會自動追加數以解決名稱衝突。在這裏看到類似的問題:Why does EntityFramework append a 1 by default in edmx after the database entities?

任何機會,你有什麼遊逛 - 從您的解決方案,但仍然在你的構建路徑中刪除代碼文件?你有沒有嘗試使用Windows資源管理器而不是Visual Studio搜索源文件夾?

+0

我沒有發現任何表明任何地方都有重複的東西。沒有任何EDMX文件或其他東西的副本,並且在Windows資源管理器中搜索文件只會返回任何內容。 –

+0

@MathiasLykkegaardLorenzen對於沒有標記爲partial的DatabaseSupporter,您沒有部分類? –

+0

沒有。如果我將該類更改爲非部分,它仍然編譯。 –

7

這種映射是不正確的:

modelBuilder 
    .Entity<DatabaseSupporter>() 
    .Map(m => 
    { 
     m.Property(s => s.Id) 
      .HasColumnName("Id"); 
     m.ToTable("DatabaseSupporter"); 
    }); 

它是Entity Splitting種映射的50% - 其存儲在由連接的兩個(或甚至更多)單獨的表的單個實體的屬性的映射數據庫中的一對一關係。因爲映射是不完整的,你甚至沒有得到實體分割正確映射。特別是EF似乎假定包含其它屬性(未明確在映射片段構造)第二個表應具有名稱DatabaseSupporter1。我可以用EF 6重新創建它(順便說一句,在映射片段中添加了一個Property方法來配置單個屬性。在早期版本中,該方法不存在(只有Properties方法)。)另外,一對一在數據庫中沒有正確創建約束。在我看來EF應該拋出約一個不正確映射一個例外而不是在這裏的安靜無聲地映射到廢話也不例外。

無論如何,您可能不想將實體屬性拆分爲多個表,但將其映射到單個表。然後,您必須替換代碼塊的上方通過:

modelBuilder.Entity<DatabaseSupporter>() 
    .Property(s => s.Id) 
    .HasColumnName("Id"); 

modelBuilder.Entity<DatabaseSupporter>() 
    .ToTable("DatabaseSupporter"); 

第一映射似乎是多餘的,因爲財產Id將默認被映射到具有相同名稱的列。第二映射是可能也是多餘的(取決於如果表名多元化被接通或不)。您可以在沒有此映射的情況下嘗試。在任何情況下,你不應該再得到一個異常報告缺少dbo.DatabaseSupporter1

1
modelBuilder 
    .Entity<DatabaseSupporter>() 
    .HasMany(s => s.DatabaseGroups) 
    .WithMany(g => g.DatabaseSupporters) 
    .Map(m => 
    { 
     m.ToTable("DatabaseSupporterDatabaseGroup"); 
     m.MapLeftKey("DatabaseGroups_Id"); 
     m.MapRightKey("DatabaseSupporters_Id"); 
    }); 

左右兩邊在許多對象上反轉。 試試這個:

modelBuilder 
    .Entity<DatabaseSupporter>() 
    .HasMany(s => s.DatabaseGroups) 
    .WithMany(g => g.DatabaseSupporters) 
    .Map(m => 
    { 
     m.ToTable("DatabaseSupporterDatabaseGroup"); 
     m.MapLeftKey("DatabaseSupporters_Id"); 
     m.MapRightKey("DatabaseGroups_Id"); 
    }); 
2

我複製了你的模型完全按照您列出它,我不能重現目前在DDL您的問題是,EDMX表面從模型生成數據庫時發出。

您能否提供詳細信息,確切瞭解如何在DatabaseGroup和DatabaseSupporter之間添加多對多關係?你說你試圖將關係添加到edmx表面上,而不是通過代碼,它會在你的表名上起作用?

我說這個東西很多一對多從DatabaseGroup到DatabaseSupporter 我說這東西多到許多從DatabaseSupporter到DatabaseGroup

能否請您提供以下信息:

回滾到您的代碼庫在添加多對多關係之前。確保您的EF Fluent API代碼目前不在您的項目中。

  • 從該表面生成DDL並確認它沒有被與 它選擇在該階段的名稱DatabaseSupporters1(後表名生成 。DatabaseSupporter或DatabaseSupporters)

現在,右鍵單擊DatabaseGroup |添加新| | Association

  • 選擇DatabaseGroup爲左側,DatabaseSupporter爲 右側。確認協會,設計師 選用的是DatabaseGroupDatabaseSupporter的名字[不要創建]
  • 選擇DatabaseSupporter左和DatabaseGroup爲 權利。確認協會,設計師 選用的是DatabaseSupporterDatabaseGroup的名字[創建]

從EDMX面上,右鍵單擊許多-to-many關聯剛剛創建,並單擊「顯示在模型瀏覽器」

  • 編輯您的帖子以包含顯示的設置。

另外,右鍵單擊曲面並單擊「從模型生成數據庫」。

  • 編輯您的帖子以包含生成的DDL。該表 應該被命名爲[DatabaseSupporters]

(我的第一個傾向是,這將有事情做與您的導航性能,但不能完全肯定。我其實是有實體框架做同樣的事情給我玩具項目我工作,但我記得它是瑣碎改正,我不記得的根本原因是什麼,我似乎記得它是一些關於導航性能)

[編輯] 等待.....

如果我刪除了不能解決我的問題的多對多問題。但是, 恢復之前,我添加了多對多的修復它。已經顯示引發異常的確切代碼 。如果我完全刪除我的流利 映射,它不是拋出相同的例外(它拋出 某事關於一個組和一個支持者,並且一個主體)。我沒有 試圖在一個空的項目中重新創建模型 - 這需要大量的 時間。我已經嘗試在記事本中搜索EDMX以供參考 - 沒有被發現。

(注意我強調) 所以DatabaseSupporter1錯誤出現了,你想你的流暢API補丁之後?擺脫補丁,添加多對多,然後給我們真正的錯誤。

......另外,花了5分鐘建立這個圖。我不會認爲這是「很多時間。「

+0

是的,我認爲流暢的解決方法是不必要的,並且更好地集中於使EF正常播放球。從頭重新創建和分析SQL是一種更好的方法。 – Rory

1

我覺得DatabaseSupporter類創建兩個時間

一個名字是:DatabaseSupporter

另一個是:DatabaseSupporter1

修改後的更改存儲在DatabaseSupporter1和映射到這裏

您需要複製DatabaseSupporter1類代碼並將代碼複製到DatabaseSupporter cl屁股。然後刪除這個DatabaseSupporter1類。