实体框架:查询多态导航属性

时间:2014-05-04 17:34:01

标签: c# entity-framework ef-code-first linq-to-entities

我有一个名为Favorite的基类:

public abstract class Entity
{
     public int Id { get; set; }
}

public abstract class Favorite : Entity
{
    public DateTime WhenCreated { get; set; }
    public string Comments { get; set; }
}

2个具体的课程,FavoriteQuestionFavoriteArticle

public class FavoriteQuestion : Favorite
{
    public virtual Question Question { get; set; }
}

public class FavoriteArticle : Favorite
{
    public virtual Article Article { get; set; }
}

这将创建以下表模式:

Id, WhenCreated, Comments, Question_Id, Article_Id, Discriminator

现在,我有这个处理收藏过程的服务方法,需要检查是否已有TFavoriteQuestion / FavoriteArticle)已通过{{1 }}

itemId

如何编写多态LINQ查询以确定给定public int Favorite<T>(int itemId) where T : Favorite { var isExists = db.Set<T>().Any(x => x. ???) } T是否存在记录?

(请注意,itemIdQuestion都直接从Article继承,并且不共享任何其他基类。

更新

以下是曝光的相关Entity

DbSets

2 个答案:

答案 0 :(得分:1)

这里的问题是 NOT 多态。

我认为你需要的是一个Item类,派生自实体,问题和文章来自。

public class Item : Entity {...}

public class Article : Item {...}
public class Question : Item {...}

然后您可以将项目添加到收藏夹

public abstract class Favorite : Entity
{
    ...
    public Item Item { get; set; }
}

然后你可以这样做:

public int Favorite<T>(int itemId) where T : Favorite
{
    var isExists = db.Set<T>().Any(x => x.Item.Id == itemId)
    ...
}

当然,这将允许将一个问题添加到FavoriteArticle ...但是EF不会处理机制泛型,所以你在这里有一些限制,你最终必须在代码中强制执行约束。

或者,您可以将Item的类型设置为Entity,但随后它会扩展可用于包含FavoriteQuestion和FavoriteArticle的类型。但它会摆脱仅用于缩小类型的额外类型。

编辑:

在您的DbContext中包含实体,否则您将收到错误。

public IDbSet<Entity> Entities {get; set;}
public IDbSet<Question> Questions { get; set; }
public IDbSet<Article> Articles { get; set; }
public IDbSet<Favorite> Favorites { get; set; }

答案 1 :(得分:0)

x => 
(x as FavoriteQuestion).Question.Id == itemId 
|| 
(x as FavoriteArticle).Article.Id == itemId 

是否应该工作?