实体框架带有列表的复杂对象

时间:2014-02-26 18:12:53

标签: entity-framework object code-first asp.net-mvc-5 complextype

这是我关于堆栈溢出的第一个问题所以我会尽量准确。 这是我的模特:

    namespace GRHMeca.Models
    {
        public class Projet
        {
            [Key]
            public int ID { get; set; }

            [Required]
            public String Nom { get; set; }

            public String Description { get; set; }
            public List<Membre> Membres { get; set; }
        }
    }

和Membre是另一种常规模式。

我面临的问题如下: 如果我这样做:

    Projet projet = db.projets.Find(id);
    IList<Membre> SelectionList = projet.Membres.ToList();

我得到一个空指针异常; 但这很好用:

    IEnumerable<Membre> SelectionList = new List<Membre>();
    SelectionList = db.Membres
    .ToList()
    .AsEnumerable<Membre>()
    .Except<Membre>(
        db.Membres
            .ToList()
            .AsEnumerable<Membre>()
            .Except<Membre>(
                projet.Membres
                .ToList()
                .AsEnumerable<Membre>()
            )
        )
    .ToList();

我正在使用实体框架6,MVC 5和代码优先迁移。 现在我有点担心性能,我想知道这个问题的原因以及如何避免它。

非常感谢

1 个答案:

答案 0 :(得分:11)

当您调用Find实体框架从数据库加载实体但未加载其导航属性(引用其他实体的属性)时 - 如Membres集合。由于未加载或初始化为空集合,因此当您在NullReferenceException上致电.ToList()时,您会收到projet.Membres

这里有两种选择。将virtual关键字添加到集合中......

public virtual List<Membre> Membres { get; set; }

...这将使EF在访问时“懒洋洋地加载”该集合(这是第二个数据库查询)。或者使用Include方法在单个查询中加载projetMembres集合:

Projet projet = db.projets.Include(p => p.Membres)
    .SingleOrDefault(p => p.ID == id);
IList<Membre> SelectionList = projet.Membres;

(将using System.Data.Entity;添加到您的代码文件中,以使{lambner表达式的Include方法可用。)

我更喜欢你的第二个选项,因为你事先知道要加载父实体和子集合。

您可以阅读有关加载相关实体here的更多信息。