2012-10-16 68 views
1

我正在努力將現有的Ruby on Rails應用程序的一部分移植到.NET MVC 4和實體框架5(不要問),並且需要一些幫助來複制某些ORM功能,特別是Rails的多態關聯。等效於實體框架中的Rails多態關聯

我寧願不改變現有的數據庫結構。我給的我在做什麼一個例子 - 這裏的數據庫是什麼樣子:

CREATE TABLE tags (
    id integer PRIMARY KEY, 
    name nvarchar(128) NOT NULL, 
    UNIQUE (name) 
); 

CREATE TABLE taggings (
    id integer PRIMARY KEY, 
    tag_id integer REFERENCES tags(id) ON DELETE CASCADE, 
    taggable_id integer, 
    taggable_type nvarchar(255), 
); 

CREATE TABLE stories (
    id integer PRIMARY KEY, 
    name nvarchar(128) NOT NULL 
    [more stuff] 
); 

CREATE TABLE assets (
    id integer PRIMARY KEY, 
    name nvarchar(128) NOT NULL 
    [more stuff] 
); 

該模型的Tagging在此表看起來與其他幾人,諸如故事,資產等相關記錄如:

INSERT INTO taggings values (1, 1, 1234, 'Story'); 
INSERT INTO taggings values (2, 343, 69, 'Asset'); 
INSERT INTO taggings values (3, 200, 42, 'Asset'); 

因此,域中的資產模型和故事模型都與標籤具有一對多關係。我想在我的C#Story和Asset類中建模(Fluent API)這種關係。

有沒有一種方法來指定這個,或許在定義關係時使用附加條件(Tagging.taggable_type ='Story')?我不需要導航到其他方向(從標記到故事/資產)。

+0

相關文檔:[Rails Guides](http://guides.rubyonrails.org/association_basics.html#polymorphic-associations) – Pete

回答

2

使EF行爲像ActiveRecord它不會工作,但你可以做類似的事情。 你有一個類似於多態類的Taggable,並且該類具有並且屬於許多標籤,其他類繼承自Taggable,使它們成爲「Taggable」,例如Article:Taggable,因此在對象內部,您將擁有類似

article.Tags - >因爲文章是可標記的而Taggable有很多標籤。

下面是測試代碼和工作

`

public class Tag 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public List<Taggable> Taggables { get; set; } 
} 

public class Taggable 
{ 
    public int Id { get; set; } 
    public List<Tag> Tags { get; set; } 
} 

[Table("Quests")] 
public class Quest : Taggable 
{ 
    public string Name { get; set; } 
    public string QuestType { get; set; } 
} 

[Table("Articles")] 
public class Article : Taggable 
{ 
    public string Name { get; set; } 
    public string ArticleType { get; set; } 
} 

public class Repository : DbContext 
{ 
    public Repository() : base("Blog") 
    { 
    } 

    public DbSet<Tag> Tags { get; set; } 
    public DbSet<Taggable> Taggables { get; set; } 
} 

`

所以你可以做這樣的東西

`

 Repository r = new Repository(); 
     Article a = new Article(); 
     a.Tags = r.Tags.ToList(); 
     a.Name = "article 1"; 
     r.Taggables.Add(a); 

     Quest q = new Quest(); 
     q.Tags = r.Tags.ToList().Skip(2).ToList(); 
     r.Taggables.Add(q); 

     r.SaveChanges(); 

     var bb = from ttt in r.Taggables 
       where ttt is Article 
       select ttt; 

     var jj = bb.ToList(); 

`

我希望我解決了你的問題。