0

将 MVC4 与 Entoty Framework CodeFirst 一起使用我在以下场景中遇到问题:

public class Survey
{

    public QuestionCollection Questions {get;set;}
}

public class QuestionCollection : List<IQuestion> //Just for MVC
{ }

public class QuestionType1 : IQuestion { ... }
public class QuestionType2 : IQuestion { ... }

看起来很简单。现在在我的控制器中,我想获得调查,所以我有:

DataContext context = new DataContext ();

var survey = context.Surveys.Include(s => s.Questions).SingleOrDefault(s => s.Id == id);

它确实编译但运行时它给了我错误:

指定的包含路径无效。EntityType“调查”未声明名为“问题”的导航属性。

我在这里做错了什么?有没有关于这个主题的好教程?

4

2 回答 2

1

Entity Framework Code First 要求将导航集合声明为ICollection<T>. 此外,为了启用关联的延迟加载,它应该是虚拟的。这是因为,除非另有说明,否则 EF 将返回包装您声明的类的代理对象。由于您的原始QuestionCollection属性是一个具体的实现,它不能在代理中覆盖它并启用导航。Questions必须声明为接口。

您在 EF 中的关注点和要求与在 MVC 中不同,并且它们并不总是兼容的。如果你真的,真的想要QuestionCollection,你将不得不映射它。

您的调查实体应如下所示:

public class Survey
{
    public virtual ICollection<Question> Questions { get; set; }
}

此外,EF 无法实现声明为接口的实体类型。这不起作用:public virtual ICollection<IQuestion>- 您的各个问题类型必须全部继承自一个共同的抽象或具体实例。它们仍然可以实现接口,但您的实体类型属性不能以这种方式声明。

我强烈建议阅读关于 EF 中的继承结构的这一系列博客文章

您设置问题实体的方式如下所示:

// You can still keep the IQuestion interface around for MVC
public abstract class Question : IQuestion
{
    // ... properties ...
}

public class QuestionType1 : Question
{
    // ... properties ...
}

public class QuestionType2 : Question
{
    // ... properties ...
}

public class Survey
{
    // Note, collection of Question, not the interface.
    public virtual ICollection<Question> Questions { get; set; }
}

根据您希望表结构的外观,基Question类可能是抽象的,也可能不是抽象的。请参阅上面的博客文章以查看各种选项 - 每个类型的表、每个层次结构的表、每个具体的表。

于 2013-07-22T13:55:24.797 回答
0

看看这个链接,我认为你需要设置一些自动策略 http://forums.asp.net/t/1816051.aspx/1

于 2013-07-22T12:36:52.057 回答