2

我正在使用 C#/.net 4.5 和 EF 6 创建一个应用程序,并且想知道是否可以以某种方式执行以下操作:

我有两个基类,例如:

public class BaseItem
{
    [Key]
    public int Id { get; set; }

    public List<BaseRevision> Revisions { get; set; }
}

public class BaseRevision
{
    [Key]
    public int Id { get; set; }

    public BaseItem Item { get; set; }
}

现在我将它们都推导如下:

[Table("ContentItems")]
public class ContentItem : BaseItem
{
    public string ContentType { get; set; }
}

[Table("ContentRevisions")]
public class ContentRevision : BaseRevision
{
    public string Text { get; set; }
}

这可以正常工作,EF 甚至可以处理以下查询:

var revisions = db.ContentItems.Where(i => i.Revisions.Any(r => (r as ContentRevision).Text.Contians("ABC")));

正如我所期望的那样,这将转换为 SQL,但我想“摆脱as”(它在其他一些情况下会导致更多的复杂性)。

我尝试使用泛型BaseItem,但 EF 不支持,所以我尝试了以下方法:

[Table("ContentItems")]
public class ContentItem : BaseItem
{
    public string ContentType { get; set; }

    public List<ContentRevision> ContentRevisions { get; set; }
}

[Table("ContentRevisions")]
public class ContentRevision : BaseRevision
{
    public string Text { get; set; }

    public ContentItem ContentItem { get; set; }
}

所以我可以使用上面的查询,如:

var revisions = db.ContentItems.Where(i => i.ContentRevisions.Any(r => r.Text.Contians("ABC")));

但我无法使用“BaseItems”表中继承的外键“Item_Id”让它工作。EF 总是希望使用“ContentItems”表中的新“ContentItem_Id”键创建第二个 FK-Relation,这将复制关系(并可能导致其他一些副作用)。

这是否可能(或者有人有更好的想法来解决/改进这个问题/模式)?

更新:演示项目可以在这里下载。如果您添加一个新的迁移,它将创建我不想要的第二个 FK 映射......

4

3 回答 3

1

编辑 :

您无需在此处添加复杂的关系,这正是 OfType<> 的用途。

当您只想访问您的 ContentItems 时,而不是在继承的对象中创建一个新列表,您可以使用 BaseItem 列表并编写:

(i is a BaseItem)
i.Revison.OfType<ContentItem>

您将使用此通用列表来存储所有不同的 BaseItem。多亏了编译器,它没有开发人员错误,因为当使用 OfType<> 函数时,你只会得到你想要的类型化对象。

初始答案: 如果您最初的问题是所有修订都不是 ContentRevision 并且它导致您的查询在as转换时失败,您应该这样写:

var revisions = db.ContentItems.Where(i => i.Revisions.OfType<ContentRevision>.Any(r => r.Text.Contains("ABC")));
于 2013-09-14T08:52:42.553 回答
0
 public class BaseItem
 {
   [Key]
   public int Id { get; set; }

   public List<BaseRevision> Revisions { get; set; }
  }

 public class BaseRevision
 {
    [Key]
    public int Id { get; set; }

    public Int BaseItemID{get;set;}
    [ForeignKey("BaseItemID")]
     public BaseItem Item { get; set; }
  }
于 2013-09-13T14:28:28.447 回答
0

您是否尝试过使用 ForeignKey 数据注释来告诉实体框架哪些属性用于外键。IE

public class BaseItem
{
  [Key]
  public int Id { get; set; }

  public List<BaseRevision> Revisions { get; set; }
}

public class BaseRevision
{
  [Key]
  public int Id { get; set; }

  [ForeignKey("Id")]
  public BaseItem Item { get; set; }
}

[Table("ContentItems")]
public class ContentItem : BaseItem
{
    public string ContentType { get; set; }
}

[Table("ContentRevisions")]
public class ContentRevision : BaseRevision
{
  public string Text { get; set; }
}

或使用 Fluent API 指定关系,即 BaseItem 类

modelBuilder.Entity<BaseItem>()
.HasMany(t => t.Revisions)
.WithRequired(t => t.Item)
.HasForeignKey(t => t.Id);
于 2013-09-09T12:33:48.760 回答