1

我正在努力将现有 Ruby on Rails 应用程序的一部分移植到 .NET MVC 4 和 Entity Framework 5(不要问),并且需要一些帮助来复制一些 ORM 功能,尤其是 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]
);

Taggings 模型与其他几个相关联,例如 Story、Asset 等。此表中的记录如下所示:

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

因此,域中的 Asset 和 Story 模型都与 Taggings 具有一对多的关系。我想在我的 C# Story 和 Asset 类上建模(Fluent API)这种关系。

有没有办法在定义关系时指定这一点,也许还有一个附加条件(Tagging.taggable_type = 'Story')?我不需要导航另一个方向(从标记到故事/资产)。

4

1 回答 1

2

Make EF acts like ActiveRecord it's not going to work, but you can do something similar. You have a class Taggable that acts like the polymorphic class and that class has and belongs to many Tags, your other classes inherit from Taggable that makes them "Taggable" so for example Article : Taggable so inside the object you will have something like

article.Tags -> because article is Taggable and a Taggable has many Tags.

Below is the code tested and working

`

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; }
}

`

so you can do stuff like this

`

        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();

`

I hope I solved your question.

于 2013-01-07T15:24:26.487 回答