Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF4 code first adding items not very clear to me

I don't understand why code first does not add a new item to the collection until after calling savechanges. I installed EF4.1 from NuGet (4.1.10331.0). I created the following example:

public class TinyItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class TinyContext : DbContext
{
    public virtual DbSet<TinyItem> Items { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        using (var ctx1 = new TinyContext())
        {
            ListItems(ctx1, "Start");

            ctx1.Items.Add(new TinyItem { Name = "Test1" });
            ListItems(ctx1, "After add");

            ctx1.SaveChanges();
            ListItems(ctx1, "After commit");
        }

        Console.ReadKey();
    }

    public static void ListItems(TinyContext ctx, string label="")
    {
        Console.WriteLine("=========================================");
        Console.WriteLine(label);
        Console.WriteLine(string.Format("Items.Local: {0}", ctx.Items.Local.Count));
        foreach (var item in ctx.Items.Local)
        {
            Console.WriteLine(string.Format("{0} = {1}", item.Id, item.Name));
        }
        Console.WriteLine(string.Format("Items: {0}", ctx.Items.Count()));
        foreach (var item in ctx.Items)
        {
            Console.WriteLine(string.Format("{0} = {1}", item.Id, item.Name));
        }
        Console.WriteLine("=========================================");
    }

First I added one record to the database. Then I ran this and these are the results:

    =========================================
    Start
    Items.Local: 0
    Items: 1
    4 = Test1
    =========================================
    =========================================
    After add
    Items.Local: 2
    4 = Test1
    0 = Test1
    Items: 1
    4 = Test1
    =========================================
    =========================================
    After commit
    Items.Local: 2
    4 = Test1
    5 = Test1
    Items: 2
    4 = Test1
    5 = Test1
    =========================================

My questions are: - Why does the first call to ctx.Items.Local give my zero items? - Why does the list of ctx.Items not contain the just added item before I called SaveChanges?

like image 965
John Landheer Avatar asked Oct 10 '22 14:10

John Landheer


1 Answers

Why does the first call to ctx.Items.Local give my zero items?

Because EF hasn't loaded any items from the database(or you haven't added any). Hence it is not tracking any items yet. That is shown as 0.

Here's the msdn description for Local

Returns ObservableCollection that represents entities of the set that are currently being tracked by the context and have not been marked as Deleted. Accessing the Local property never causes a query to be sent to the database. This property is usually used after a query has already been executed.


Why does the list of ctx.Items not contain the just added item before I called SaveChanges?

When you refer ctx.Items it will be fetched from database. Since there is only 1 item (you haven't called the SaveChanges() method) in the database it shows the item(s) in the database.

like image 55
Eranga Avatar answered Oct 14 '22 02:10

Eranga