none
Entityframework; CodeFirst Remove from listbox and database RRS feed

  • Question

  • Hello,

    I have followed the guide from Microsoft (http://msdn.microsoft.com/en-us/data/jj193542) how to work with entities.

    Now i'm experimenting with this and I have made a GUI Form where I can add a Blog by clicking on a button and it will show a list of all my blogs.

    If I Select one I also can delete the selected blog by BlogID

     private void btnDelete_Click(object sender, EventArgs e)
            {
                using (var dbBlog = new BlogContext())
                {
                    string text = lstBlog.SelectedItem.ToString();
                    if (text != "")
                    {
                        var item = lstBlog.SelectedIndex+1;
                        var qry = dbBlog.tblBlogs.Where(i => i.BlogID == item);
    
                        foreach (var a in qry)
                        {
                           // MessageBox.Show(a.BlogID.ToString());
                           //   dbBlog.tblBlogs.Remove(a);
                        //    dbBlog.SaveChanges();
                           
                        }
    
                    }
                    Refresh();
                }
            }
    
    private void RefreshList()
            {
                using (var dbBlog = new BlogContext())
                {
                    var qry = dbBlog.tblBlogs.Select(t => t.BlogTitel);
                    foreach (var item in qry)
                    {
                        lstBlog.Items.Add("BlogTitle:" + item + "\n");
                    }
                }
    
            }

    This is my definition

    public class Blog
        {
            public int BlogID { get; set; }
            public string BlogTitel { get; set; }
        }
    
        public class BlogContext : DbContext
        {
            public DbSet<Blog> tblBlogs { get; set; }
        }

    When I click on btnDelete I get a message See below for a printscreen

    error

    Thnx!

    • Moved by Lisa Zhu Monday, January 21, 2013 7:50 AM EF related
    Saturday, January 19, 2013 3:37 PM

Answers

  • Hi Eclectica;

    The reason for the line of code :

    var removeEntry = new tblBlogs() { BlogID = a};


    is because in order to delete an object from the database table that record must exist in the local data context. So because your initial query only returned a List<int> and not the entity you wanted to delete you need to create an entry in the data context with its primary key filled in and attach it to the data context. Once that is done then you need to use the Remove on that entity to change its state from Unchanged to Deleted.

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Proposed as answer by Alexander Sun Tuesday, January 22, 2013 7:35 AM
    • Marked as answer by Alexander Sun Wednesday, January 30, 2013 8:35 AM
    Saturday, January 19, 2013 7:05 PM

All replies

  • Hi Eclectica;

    I am going to assume that the three statements in the foreach statement are NOT commented out when you ran the code and got the exception. Also the last statement, should that be RefreshList?

    In your code you select the item that was selected in the List plus 1 using this statement:

    var item = lstBlog.SelectedIndex+1;

    Then you use that index value as the tblBlogs.BlogID to compare to but that may not be the case. For example let say you select the third element in the list but it represents the element in the table with BlogID of 45 then your query may not return a row from the database because there may not be a BlogID with a value of 3 which was the index you used. In that case the List returned from the query is empty

    private void btnDelete_Click(object sender, EventArgs e)
    {
        using (var dbBlog = new BlogContext())
        {
            string text = lstBlog.SelectedItem.ToString();
            if (text != "")
            {
                var item = lstBlog.SelectedIndex+1;
                var qry = dbBlog.tblBlogs.Where(i => i.BlogID == item);
    
                foreach (var a in qry)
                {
                   // Are these really commented out ??
                   
                   // MessageBox.Show(a.BlogID.ToString());
                   // dbBlog.tblBlogs.Remove(a);
                   // dbBlog.SaveChanges();
                   
                }
    
            }
            
            // Should this be Refresh?
            
            Refresh();
        }
    }
    

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Saturday, January 19, 2013 4:16 PM
  • Hi Fernando

    Thanks for your reply, I work now whit my titles

    But what Do I need to insert between my remove function? An entity ...

     private void button2_Click(object sender, EventArgs e)
            {
                using (var dbBlog = new BlogContext())
                {
                    string text = lstBlog.SelectedItem.ToString();
                    
    
                    if (text != "")
                    {
                      
                        var qry = dbBlog.tblBlogs.Where(i => i.BlogTitel == text).Select(t => t.BlogID);      
    
                        foreach (var a in qry)
                        {
                            MessageBox.Show(a.ToString());
                            dbBlog.tblBlogs.Remove(WHAT DO I NEED TO WRITE HERE HE EXPECTS MY ENTITY BLOG);
                           dbBlog.SaveChanges();
                        }
                    }
                    RefreshList();
                }
            }

    Saturday, January 19, 2013 4:49 PM
  • Hi Eclectica;

    Try making the following changes to your code.

    private void button2_Click(object sender, EventArgs e)
    {
        using (var dbBlog = new BlogContext())
        {
            string text = lstBlog.SelectedItem.ToString();
            
            if (text != "")
            {
              
                var qry = dbBlog.tblBlogs.Where(i => i.BlogTitel == text).Select(t => t.BlogID);      
    
                // Us the ToList on the qry in the foreach loop
                foreach (var a in qry.ToList())
                {
                    MessageBox.Show(a.ToString());
                    // Create a record to attach to the DbContext with the record ID to delete
                    var removeEntry = new tblBlogs() { BlogID = a};
                    dbBlog.tblBlogs.Attach(removeEntry);
                    // Now mark the record just attached to be Remove
                    dbBlog.tblBlogs.Remove(removeEntry);
                    dbBlog.SaveChanges();
                }
            }
            
            RefreshList();
        }
    }

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Saturday, January 19, 2013 6:04 PM
  • Hi Fernando Many thanks, It works!

    Indeed I need to use the following line

    var removeEntry = new tblBlogs() { BlogID = a};

    If I'm right you use function attach to attach my blog with the selected ID on a already existing blog in my table? Right?

    Saturday, January 19, 2013 6:22 PM
  • Hi Eclectica;

    The reason for the line of code :

    var removeEntry = new tblBlogs() { BlogID = a};


    is because in order to delete an object from the database table that record must exist in the local data context. So because your initial query only returned a List<int> and not the entity you wanted to delete you need to create an entry in the data context with its primary key filled in and attach it to the data context. Once that is done then you need to use the Remove on that entity to change its state from Unchanged to Deleted.

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Proposed as answer by Alexander Sun Tuesday, January 22, 2013 7:35 AM
    • Marked as answer by Alexander Sun Wednesday, January 30, 2013 8:35 AM
    Saturday, January 19, 2013 7:05 PM