tabs ↹ over ␣ ␣ ␣ spaces

by Jiří {x2} Činčura

DbSet<T>.Local property (EFv4, CTP5)

9 Dec 2010 Entity Framework

Currently latest CTP for Entity Framework, CTP5, contains one new property on DbSet. It's called `Local` and it's very useful when you wanna work with objects you have already in memory. So it's good for queries without hitting the database, like databinding.

You can create layer that loads objects your application needs, or you think it might need. And then you use only .Local to access that data, still full LINQ support etc. This may help to lower number of queries you’re sending to database. The property is of type ObservableCollection, thus the databinding is super easy.

The method isn’t something new. In fact it’s exposing in a friendly was what’s already possible - i.e. Useful Find method on DbSet and “Local” Queries 2nd edition. It is using ObjectStateManager to find all Unchanged, Added and Modified entities, exactly the ones you’re probably interested in.

Let’s see some example:

class Program
{
	static void Main(string[] args)
	{
		/*
		 * I have 3 rows in FOOBAR table in database.
		 */
		using (MyContext c = new MyContext())
		{
			// return's 2 rows and hits database
			var data1 = c.Set<FooBar>().OrderBy(x => x.ID).Take(2).ToArray();
			// return's 2 rows without hitting database
			var data2 = c.Set<FooBar>().Local.ToArray();
			// return's 1 row and hits database
			var data3 = c.Set<FooBar>().OrderBy(x => x.ID).Skip(2).Take(1).ToArray();
			// return's 3 rows without hitting database
			var data4 = c.Set<FooBar>().Local.ToArray();
		}
	}
}
class MyContext : DbContext
{
	public MyContext()
		: base(new FbConnection("database=localhost:rrr.fdb;user=sysdba;password=masterkey"), true)
	{ }
	protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
	{
		base.OnModelCreating(modelBuilder);
		modelBuilder.Entity<FooBar>().HasKey(x => x.ID);
		modelBuilder.Entity<FooBar>().Property(x => x.ID).HasColumnName("ID");
		modelBuilder.Entity<FooBar>().Property(x => x.Something).HasColumnName("S");
		modelBuilder.Entity<FooBar>().Map(m => m.ToTable("FOOBAR"));
	}
}
class FooBar
{
	public int ID { get; set; }
	public string Something { get; set; }
}

All important stuff about behavior is in comments. As you see, it acts as kind of local cache of objects, that are (mostly) reasonable to work with.

As always, nothing huge, but nice, handy.

PS: Did you noticed, I’m using Firebird? ;)