简体   繁体   中英

Insert Records in multiple table which are dependent on primary / foreign key using Linq-to-SQL

I have 3 tables:

  1. master_upload (master upload has primary key with auto increment named master_upload_id)

  2. master_upload_files (this consist of 2 columns and refer master_upload_id from above table )

  3. master_upload_tags (same as second)

in 2nd and 3rd table there can be multiple rows for 1st table.

Now to insert in 2nd and 3rd table I need a master_upload_id which I only get after inserting. Hence I had to call db.SubmitChanges at least 3 times. If there are multiple values for 2nd and 3rd table I had to call db.SubmitChanges for each row in those two table. But some times the insertion in 2nd or 3rd table can fail due to some rule violation.

Hence I need to roll back in these cases. How can I do that?

I use to do these things via a SQL Server stored procedure, but now I need to do it in LINQ.

// Here is my code sample
using (dbDataContext db = new dbDataContext())
{
    db.master_uploads.InsertOnSubmit(mu);// toget mu.upload_id

    try
    {
        db.SubmitChanges();
        master_upload_file mf = new master_upload_file();
        mf.master_upload_id = mu.upload_id;
        mf.upload_file_id = uploadedfile.file_id;

        db.master_upload_files.InsertOnSubmit(mf);

        for (int i = 0; i < tags.Length; i++)
        {
            master_upload_tag mt = new master_upload_tag();
            mt.master_upload_id = mu.upload_id;
            mt.tag = tags[i];
            db.master_upload_tags.InsertOnSubmit(mt);
        }

        db.SubmitChanges();
        gtu.writetext("0",context);
    }
    catch (Exception)
    {
        gtu.writetext("1:File Upload Add Error", context);
    }
}

I am using SQL Server 2008.

Thanks

You're doing this way too complicated! Use the force, man!! :-)

Try this code:

// define your context
using (UploadContextDataContext ctx = new UploadContextDataContext())
{
    try
    {
        // create your new upload
        upload up = new upload();
        up.UploadName = "Some test name";

        // define two new upload files 
        UploadFile file1 = new UploadFile { FileName = "TestFile1.zip" };
        UploadFile file2 = new UploadFile { FileName = "TestFile2.zip" };

        // *ADD* those two new upload files to the "Upload"
        up.UploadFiles.Add(file1);
        up.UploadFiles.Add(file2);

        // define three new upload tags
        UploadTag tag = new UploadTag { TagName = "Tag #1" };
        UploadTag tag2 = new UploadTag { TagName = "Tag #2" };
        UploadTag tag3 = new UploadTag { TagName = "Tag #3" };

        // *ADD* those three new upload tags to the "Upload"
        up.UploadTags.Add(tag);
        up.UploadTags.Add(tag2);
        up.UploadTags.Add(tag3);

        // add the "Upload" to the context - this *INCLUDES* the files and tags!
        ctx.uploads.InsertOnSubmit(up);

        // call SubmitChanges *just once* to store everything!
        ctx.SubmitChanges();
    }
    catch (Exception exc)
    {
        string msg = exc.GetType().Name + ": " + exc.Message;
    }

You basically set up an object graph - your basic Upload object - and you add your files and tags to that Upload object. You only need to add that Upload object to the data context - the other (added) subobjects are tagging along automatically !

And in this case, you only need to call SubmitChanges() a single time and this will insert all the new objects, set up all the necessary foreign key / primary key relationships and all for you. No fiddling around with primary keys, multiple calls to the database - just use the magic of Linq-to-SQL!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM