Signum Framework Logo
"Open framework that encourages convention over configuration, using C# code,
not XML files, to model at the right level of abstraction and achieve deadlines.
...but also has a full Linq provider, and syncs the schema for you!"
Login
RSS

Search

»



Main
Index
Map
Videos
Download
Source code
Tutorials
Forum
FAQ



Image



PoweredBy

Introduction

ObjectCache uses Scope pattern to make a simple model for developers to keep the identity of objects in a region of your code.

If you want to cache some objects so they are the same across some database operations, just surround them with a ObjectCache scope.

The Problem

If you execute a code like this:

  DeveloperDN developer = Database.Retrieve<DeveloperDN>(3);
  Console.WriteLine(developer.Name);

var bugs = Database.Query<BugDN>().Where(b => b.Fixer.Id == 3).ToList(); Console.WriteLine(bugs[0].Fixer.Name);

Console.WriteLine(bugs[0].Fixer == developer);

You produce the following output:

Luís
Luís
False


As you can see, Luis entity is retrieved twice, in the first line and in the query, so we have two different in memory instances of the same entity. This could be problematic in some scenarios because you could make on one but not the other, etc...

Notice that we override Equals method to use entity id and type, but not operator ==

The Solution

As we see in Database - Retrieve, keeping the identity of objects is a hard problem to solve when writing an Object-Relational Mapping technology. In order to make it completely transparent it's necessary to maintain huge data structures with all the previously retrieved and saved objects.

In our opinion, a solution like this doesn't make sense because usually you just don't need to keep identity at all, and it takes memory.

What we provide, instead, is the ability to control how widely this scope will be using ObjectCache.

Fixing the last problem is as easy as surrounding it with new ObjectCache:

using (new ObjectCache())
{
  DeveloperDN developer = Database.Retrieve<DeveloperDN>(3);
  Console.WriteLine(developer.Name);

var bugs = Database.Query<BugDN>().Where(b => b.Fixer.Id == 3).ToList(); Console.WriteLine(bugs[0].Fixer.Name);

Console.WriteLine(bugs[0].Fixer == developer); }

Writing in the console:

Luís
Luís
True


Internally it just creates a wider ObjectCache (just a dictionary of objects by type and If) that wraps every operation (Save and Retrieve, even on queries). Avoiding each operation from having its' own isolated one.

Currently nested ObjectCache became silent, as Transactions. Maybe in the future, if we found it valuable, we would add support for stacked ObjectCache.

Finally, you can manually add some objects to an object cache like this:

var developer = Database.Retrieve<DeveloperDN>(3);
Console.WriteLine(developer.Name);

using (new ObjectCache()) { ObjectCache.Add(developer);

var bugs = Database.Query<BugDN>().Where(b => b.Fixer.Id == 3).ToList(); Console.WriteLine(bugs[0].Fixer.Name); Console.WriteLine(bugs[0].Fixer == developer); }

With identical results.
Creative Commons License Signum Framework Site by Signum Software is licensed under a Creative Commons Attribution 3.0 License.
Powered by ScrewTurn Wiki version 3.0.5.600.