在单个查询中将数据插入多个表

时间:2014-12-27 20:29:34

标签: c# sql asp.net asp.net-mvc-4

目前我正在学习ASP.NET,我坚持将数据存储到多个表中。数据库模型如下所示:

Database model

我想要实现的是当我向Contact表添加新联系人以获取最后一个插入ID并自动插入表Phone / Tag / Email的数据时(如果该表有一些数据)。是否有机会在单个查询中执行此操作,还是需要为每个表运行新查询?

这是在Controller中使用的模型:

 public partial class Contact
    {
        public Contact()
        {
            this.Emails1 = new HashSet<Email>();
            this.Phones1 = new HashSet<Phone>();
            this.Tags1 = new HashSet<Tag>();
        }

        public int id { get; set; }
        public string firstname { get; set; }
        public string lastname { get; set; }
        public string address { get; set; }
        public string city { get; set; }
        public Nullable<byte> bookmarked { get; set; }
        public string notes { get; set; }

        public virtual ICollection<Email> Emails1 { get; set; }
        public virtual ICollection<Phone> Phones1 { get; set; }
        public virtual ICollection<Tag> Tags1 { get; set; }
    }
}

这是电话/标签/电子邮件表格的模型(它在一列中的名称相同)

public partial class Email
    {
        public int id { get; set; }
        public int id_contact { get; set; }
        public string email1 { get; set; }

        public virtual Contact Contact1 { get; set; }
    }

以下是将新行广告到数据库的控制器类:

 public string AddContact(Contact contact)
        {
            if (contact != null)
            {

                db.Contacts.Add(contact);
                db.SaveChanges();
                    return "Contact Added";
            }
            else
            {
                return "Invalid Record";
            }
        }

3 个答案:

答案 0 :(得分:2)

您的Contact对象包含电子邮件,电话和标签的集合,因此在调用db.SaveChanges()之前,您可以将它们添加到Contact的集合中。

public string AddContact(Contact contact)
{
    if (contact != null)
    {
        db.Contacts.Add(contact);

        contact.Emails1.Add(new Email { Email1 = "email@email.com"})
        contact.Emails1.Add(new Email { Email1 = "email2@email.com"})

        contact.Phones1.Add(new Phone1 { PhoneNumber = "1234516123"})

        db.SaveChanges();
        return "Contact Added";
    }
    else
    {
            return "Invalid Record";
    }
}

只需确保您的外键引用设置正确,并且Contact对象具有标识列(如果它是新联系人)。

答案 1 :(得分:0)

您可以保存实体图,因为可以在this article中读取有关实体框架的内容:

//Create student in disconnected mode
Student newStudent = new Student() { StudentName = "New Single Student" };

//Assign new standard to student entity
newStudent.Standard = new Standard() { StandardName = "New Standard" };

//add new course with new teacher into student.courses
newStudent.Courses.Add(new Course() { CourseName = "New Course for single student", Teacher = new Teacher() { TeacherName = "New Teacher" } });

using (var context = new SchoolDBEntities())
{
    context.Students.Add(newStudent);
    context.SaveChanges();

    Console.WriteLine("New Student Entity has been added with new StudentId= " + newStudent.StudentID.ToString());
    Console.WriteLine("New Standard Entity has been added with new StandardId= " + newStudent.StandardId.ToString());
    Console.WriteLine("New Course Entity has been added with new CourseId= " + newStudent.Courses.ElementAt(0).CourseId.ToString());
    Console.WriteLine("New Teacher Entity has been added with new TeacherId= " + newStudent.Courses.ElementAt(0).TeacherId.ToString());
}

此代码使用scope_identity()函数获取最后添加的记录ID。

因此,据我所知,您已经为您的课程编写了完整的代码。另请注意,您应该处置DataContext

答案 2 :(得分:0)

答案是使用存储过程:

使用存储过程::

的CRUD

实体框架能够根据您的LINQ to Entities或Entity SQL查询自动为数据库构建本机命令,以及构建用于插入,更新或删除数据的命令。您可能希望覆盖这些步骤并使用自己的预定义存储过程。您可以使用存储过程来获取数据或将记录添加/更新/删除到一个或多个数据库表。

此处将使用DbContext完成创建,更新,删除操作的存储过程。这意味着上下文将在context.SaveChanges()上执行存储过程而不是DDL语句。

将使用

  1. sp_InsertStudentInfo存储过程以插入新学生 数据库
  2. sp_UpdateStudent更新学生
  3. sp_DeleteStudent删除数据库中的学生。

    CREATE PROCEDURE [dbo].[sp_InsertStudentInfo]
        -- Add the parameters for the stored procedure here
        @StandardId int = null,
        @StudentName varchar
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
         INSERT INTO [SchoolDB].[dbo].[Student]([StudentName],[StandardId])
         VALUES(@StudentName, @StandardId)
    
        SELECT SCOPE_IDENTITY() AS StudentId
    
    END
    
     CREATE PROCEDURE [dbo].[sp_UpdateStudent]
        -- Add the parameters for the stored procedure here
        @StudentId int,
        @StandardId int = null,
        @StudentName varchar
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
        Update [SchoolDB].[dbo].[Student] 
        set StudentName = @StudentName,StandardId = @StandardId
        where StudentID = @StudentId;
    
    END
    
    CREATE PROCEDURE [dbo].[sp_DeleteStudent]
        -- Add the parameters for the stored procedure here
        @StudentId int
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
        DELETE FROM [dbo].[Student]
        where StudentID = @StudentId
    
    END
    
  4. 首先,将这些存储过程添加到EDM中,并确保取消选中将所选存储的procudures和函数导入到实体模型复选框,因为我们将直接将这些过程映射到Student实体。

    enter image description here

    现在,模型浏览器会将程序添加到存储模型中,但不会添加到功能导入

    enter image description here

    现在,在EDM设计器中,右键单击Student实体并选择Stored Procedure Mapping以打开Mapping details:

    enter image description here

    在映射详细信息中,您将看到,。为每个选择适当的存储过程,例如。为插入函数选择sp_InsertStudentInfo,如下所示:

    enter image description here

    sp_InsertStudentInfo返回新的自动生成的StudentId。因此,使用Student Entity的StudentID进行映射,如下所示:

    enter image description here

    完成插入,更新和删除过程的映射,如下所示:

    enter image description here

    现在,我们需要在执行之前对其进行验证,以确保不会出现运行时错误。要完成此操作,请右键单击设计器中的Student实体,然后单击Validate并确保没有警告或错误:

    enter image description here

    现在您可以添加,更新和删除学生,如下所示:

    using (var context = new SchoolDBEntities())
    {
        Student newStudent = new Student() { StudentName = "New Student using SP"};
    
        context.Students.Add(newStudent);
        //will execute sp_InsertStudentInfo 
        context.SaveChanges();
    
        newStudent.StudentName = "Edited student using SP";
        //will execute sp_UpdateStudent
        context.SaveChanges();
    
        context.Students.Remove(newStudent);
        //will execute sp_DeleteStudentInfo 
        context.SaveChanges();
    }
    

    上面显示的代码将在每个SaveChanges()上执行以下存储过程:

    exec [dbo].[sp_InsertStudentInfo] @StandardId=NULL,@StudentName='New Student using SP'
        go
    
        exec [dbo].[sp_UpdateStudent] @StudentId=47,@StandardId=NULL,@StudentName='Edited student using SP'
        go
    
        exec [dbo].[sp_DeleteStudent] @StudentId=47
        go
    

    注意:在添加新学生后,一旦上下文调用SaveChagnes,它会将新的StudentID分配给Student实体的StudentID属性,因为sp_InsertStudentInfo返回StudentId。这是为了将该实体对象用于进一步操作所必需的。

    enter image description here

    在此处查看更多practically.