ASP.NET MVC将实体添加到ICollection

时间:2016-06-04 17:34:27

标签: c# asp.net asp.net-mvc entity-framework

我有以下控制器操作来创建用户。

    public ActionResult Create([Bind(Include = "Name, Email, Role, Password")] User user)
    {
        if (ModelState.IsValid)
        {
            // Create password hash
            user.Salt = Security.RandomString(16);
            user.Password = Security.Encrypt(user.Password, user.Salt);

            // Add Qualifications
            var qualification = db.Qualifications.Find(5);
            user.Qualifications.Add(qualification);

            // Apply changes
            db.Users.Add(user);
            db.SaveChanges();
        }
        return RedirectToAction("Index");
    }

一切正常,除了为用户添加资格认证的部分(我想添加多个资格,一旦工作)。用户模型有: public virtual ICollection<Qualification> Qualifications { get; set; }来存储资格(它是一个多对多的关系,Entitiy Framework已经创建了一个表)。

我总是收到错误:&#34;对象引用未设置为对象的实例。&#34;,在行:user.Qualifications.Add(qualification);

我不明白为什么,毕竟我确实以同样的方式添加了Salt和Password属性(并且工作正常)。此外,我确实在种子方法中为用户对象添加了多个限定条件,完全相同,它也可以正常工作。

这里的问题是什么,我该如何解决?

2 个答案:

答案 0 :(得分:1)

这是因为此资格已存在于数据库中,因为资格是虚拟的。您面临的问题是EF正在尝试再次创建它们并将新创建的内容添加到用户。

你应该在2个对象之间创建某种关系,然后分配它的id。 EF将为您处理延迟装载。

...
db.Users.Add(user);
db.SaveChanges();

qualification.AssignedUser = user.Id;
db.Entry(qualification).State = EntityState.Modified;
await db.SaveChangesAsync();

如果你这样做,你显然不能重复使用另一个用户的资格,你必须创建一个新的。如果你不想这样做,你会反过来做关系。

例如:

...
user.Qualification1Id = qualification.Id;

db.Users.Add(user);
db.SaveChanges();

答案 1 :(得分:0)

我通过实例化修复了问题:

from tkinter import * b1 = "up" xold, yold = None, None display_width = '500' display_height = '500' canvas_width = '500' canvas_height = '500' def main(): root = Tk() root.geometry((display_width+"x"+display_height)) drawing_area = Canvas(root,width=canvas_width,height=canvas_height,bg="white") drawing_area.bind("<Motion>", motion) drawing_area.bind("<ButtonPress-1>", b1down) drawing_area.bind("<ButtonRelease-1>", b1up) drawing_area.pack(side=RIGHT) root.mainloop() def b1down(event): global b1 x1, y1 = ( event.x - 4 ), ( event.y - 4 ) x2, y2 = ( event.x + 4 ), ( event.y + 4 ) event.widget.create_oval( x1, y1, x2, y2, fill = "black" ) b1 = "down" # you only want to draw when the button is down # because "Motion" events happen -all the time- def b1up(event): global b1, xold, yold b1 = "up" xold = None # reset the line when you let go of the button yold = None def motion(event): if b1 == "down": global xold, yold x1, y1 = ( event.x - 4 ), ( event.y - 4 ) x2, y2 = ( event.x + 4 ), ( event.y + 4 ) event.widget.create_oval( x1, y1, x2, y2, fill = "black" ) if xold is not None and yold is not None: python_green = "#476042" x1, y1 = ( event.x - 4 ), ( event.y - 4 ) x2, y2 = ( event.x + 4 ), ( event.y + 4 ) event.widget.create_oval( x1, y1, x2, y2, fill = "black" ) event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE,width=9) # here's where you draw it. smooth. neat. xold = event.x yold = event.y if __name__ == "__main__": main()