实体框架dbSet.Add当类链接 [英] Entity Framework dbSet.Add when classes linked

查看:110
本文介绍了实体框架dbSet.Add当类链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

为什么尝试添加一个 dbSet.Add 与EF中的其他对象相关联的对象?

Question:
Why doesn't the dbSet.Add method work when I'm attempting to add an object that's linked to other objects in EF?

详细信息

有一些背景:我是初学者与EF,我正在学习如何使用Code First来开发数据模型。

Details:
Some background on this: I'm a beginner with EF, and I'm learning how to use Code First to develop the data model.

我正在使用VS2013 Express,通过NuGet将Entity Framework 6添加到基本的MVC项目。

I'm using VS2013 Express, with Entity Framework 6 added through NuGet to a basic MVC project.

我为我的数据模型创建了三个类: Class_oneOnly Class_many Class_several Class_oneOnly 与其他两个类有一对多的关系,而另外两个类彼此之间有多对多的关系。

I've created three classes for my data model: Class_oneOnly, Class_many, and Class_several. Class_oneOnly has a one-to-many relationship to the other two classes, and the other two classes have a many-to-many relationship to each other.

我使用的是Code First,但为了解释关系的目的,这里是一个实体关系图(我在另一个项目中绘制,所以Code -First和Model-First。另外,没有预先生成的代码...虽然也许我应该这样走了,我试图学习Code First):

I'm using Code First, but for purposes of explaining the relationships, here's an entity relationship diagram (I drew this in a separate project, so there's no interference between Code-First and Model-First. Also, there is no pre-generated code...although perhaps I should have gone that way, I'm trying to learn Code First):

我可以创建每个类的新实例。

I can create new instances of each class.

但是,当我尝试执行 DbSet.Add 方法添加新的 class_many 到数据库,我收到一个错误NullReferenceException被用户代码未处理。

However, when I try to perform the DbSet.Add method to add a new instance of class_many to the database, I get an error "NullReferenceException was unhandled by user code."

这是真的,我没有在try-catch块中。但是,即使有一个try-catch块,它仍然不会解释例外:

发生了类型System.NullReferenceException的异常在EF测试代码First.dll中,但未在用户代码中处理其他信息:对象引用未设置为对象的实例。

This is true, I don't have this in a try-catch block. But, even with a try-catch block, it still wouldn't explain the exception:
"An exception of type 'System.NullReferenceException' occurred in EF Test Code First.dll but was not handled in user code. Additional information: Object reference not set to an instance of an object."

主要的问题是:为什么这个null引用被抛出,如果这一点上的所有三个类都被定义了?不应该把EF分配给链接的类通过Code First中定义的关系?

The main question is: Why is it that a null reference is being thrown, if all three classes at this point have been defined? Shouldn't EF take care of assigning properties to classes that are linked by relationships defined in Code First?

我应该在我的代码中添加一些东西来使其工作吗?

Should I add something to my code to make this work?

代码示例

设置EF DbSet:

Code Examples:
Setting up the EF DbSet:

using System.Data.Entity;

namespace EF_Test_Code_First.Models
{
    public class Context : DbContext
    {
        public Context()
            : base("name=MyContext")
        {
        }

        public DbSet<Class_many> Class_manys { get; set; }
    }
}

类定义:

public class Class_oneOnly
{
    [Key]
    public string SN { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Class_many> Class_manys { get; set; }
    public virtual ICollection<Class_several> Class_severals { get; set; }
}

public class Class_several
{
    public int ID { get; set; }
    public string Name { get; set; }

    public Class_oneOnly Class_oneOnly { get; set; }
    public virtual ICollection<Class_many> Class_manys { get; set; }
}

public class Class_many
{
    public int ID { get; set; }
    public string Name { get; set; }

    public virtual Class_oneOnly Class_oneOnly { get; set; }
    public virtual ICollection<Class_several> Class_severals { get; set; }
}

...最后但并非最不重要的是,我设置的测试代码并尝试使用DbSet.Add方法。 上下文dbContext 从控制器传递(并且是上述类中定义的静态上下文): p>

...and, last but not least, my test code that sets up the classes and attempts to use DbSet.Add method. Context dbContext is passed from the controller (and is a static Context, as defined in the class above):

public void myTest(Context dbContext)
{
    /* assign property values to oneOnly,
        * of which there is only one of these
        * in each many and each several.
        */

    Class_oneOnly oneOnly = new Class_oneOnly()
    {
        SN = "1",
        Name = "oneOnly1"
    };

    /* make sure ids are unique as the following
        * 'for' loop is iterated through
        */
    int startid;
    if (dbContext.Class_manys != null && dbContext.Class_manys.Count() > 0){
        startid = dbContext.Class_manys.Count();
    }
    else{
        startid = 0;
    }

    /* create and fill class_many and
        * class_several objects, using a new id.
        */
    for (int i = startid; i < 5; i++)
    {
        /* assign property values to many
            * and several.
            */
        Class_many many = new Class_many()
        {
            ID = i,
            Name = "many" + i.ToString()
        };

        Class_several several = new Class_several()
        {
            ID = i,
            Name = "several" + i.ToString()
        };

        /* assign further property values
            * that use navigation properties
            * to link between classes.
            */
        many.Class_oneOnly = oneOnly;
        several.Class_oneOnly = oneOnly;
        many.Class_severals.Add(several);

        /* add to EF
            */
        /*************************
            * Error occurs at this line
            *************************
            */
        dbContext.Class_manys.Add(many);
    }

    /* save
        */
    dbContext.SaveChanges();
}

我可以根据要求从项目的其他部分提供代码。 >

I can provide code from other parts of the project on request.

推荐答案

对,所以我重新创建了你的项目,并认为我发现了这个问题。第一件事:我建议将DbContext NOT 用作静态,而是使用块的。如果你仍然有问题,那就是我尝试和排除故障,以及我一直在努力做什么。如果您有全局静态上下文,那么以后您会发现更难跟踪问题。

Right, so I re-created your project and think I found the issue. First thing: I would recommend using your DbContext NOT as static, but rather in a using block. If you still have problems, that's what I did to try and troubleshoot, and what I always try to do. I think you will find it harder to track down problems later on if you've got a global, static context.

我在 many.Class_severals.Add(几); ,而不是你所说的那样。我确实使用了一个快速的Winforms项目进行故障排除,但是我不知道为什么/如果你使用上面发布的代码,你会得到一个不同的错误...无论如何,你有两个选择:你需要创建一个新的收集,如果它还没有初始化,你可以在一个构造函数或(我的偏好)在getter。

I hit a null reference error on many.Class_severals.Add(several); instead of where you said you did. I did use a quick Winforms project to troubleshoot, but I'm not sure why/how you would get a different error if you're using the code posted above... Anyhow, you have two options: you need to create a new collection if it's not already initialized, and you can do it in a constructor or (my preference) in the getter.

public class Class_many
    {
        public int ID { get; set; }
        public string Name { get; set; }

        private ICollection<Class_several> _severals;

        public virtual Class_oneOnly Class_oneOnly { get; set; }
        public virtual ICollection<Class_several> Class_severals { get
        {
            if (_severals == null) {_severals = new List<Class_several>();}
            return _severals;
        }
            set { _severals = value; }
        }
    }

这篇关于实体框架dbSet.Add当类链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆