Archive

Posts Tagged ‘c#’

NHibernate Mapping tester

August 29, 2011 2 comments

When using NHibernate, you often need to check if your mappings matches the model and database. Using frameworks like FluentNHibernate usually helps form the compilation perspective, because your mappings won’t compile if there’s any misspelled property or class. But for convensions and database schemas, it’s possible to have a mismatch.
The following code is a test that will check every property on every mapped class and then every collection. Basically, it queries each type and each collection so NHibernate needs to create the sql statement and execute it. If any error is thrown, you will notice.

[Test]
public void AllMappingsAreOk()
{
	var session = GetCurrentNHibernateSession();
	var errors = new List<string>();

	foreach (var entry in session.SessionFactory.GetAllClassMetadata())
	{
		var type = entry.Key;
		var data = entry.Value;

		try
		{
			session.CreateCriteria(type).SetMaxResults(0).List();
		}
		catch (Exception e)
		{
			errors.Add(string.Format("Error getting type {0}: {1}", type, e.Message));
		}

		foreach (var collection in data.PropertyNames.Where(x => data.GetPropertyType(x).IsCollectionType))
		{
			try
			{
				session.CreateCriteria(type).CreateCriteria(collection).SetMaxResults(0).List();
			}
			catch (Exception e)
			{
				errors.Add(string.Format("Error getting collection {0}.{1}: {2}",
										 type,
										 collection,
										 e.Message));
			}
		}
	}
	Assert.True(errors.Count == 0, string.Join(Environment.NewLine, errors));
}

This piece of code was really helpful in the past and is following me in every project involving NHibernate. It seemed useful to share ๐Ÿ™‚

Linq “in” clause

July 14, 2011 Leave a comment

So… today I needed to do a simple query like

SELECT * FROM Activities a Where a.Community in ('Community 1', 'Community 2', 'Community 3')

…with Linq.

In the objects world this is managed using the Contains method of IList. The perfect Linq for the previous query is:

var communities = new []{ "Community 1", "Community 2", "Community 3" };
var result = activities.Where(x => communities.Contains(x.Community));

The problem with this is no all Linq providers understands it. And SPLinq (Linq for SharePoint) is one of those who doesn’t.

The other way to handle this kinds of queries is, in SQL:

SELECT * FROM Activities a Where a.Community = 'Community 1' or a.Community = 'Community 2' or a.Community =  'Community 3'

But how to create the Linq query dynamically? Well… All these months working with Magiq gived me the ability of compile Expression trees in my head ๐Ÿ™‚

This is the code needed:

private static IQueryable<T> Where<T>(this IQueryable<T> self, Expression<Func<T,object>> property, IEnumerable<string> @in)
{
	var propertyName = ((MemberExpression)property.Body).Member.Name;

	Expression expression = null;

	var x = Expression.Parameter(typeof (ActivityItem), "x");
	foreach (var community in @in)
	{
		var propertyExpression = Expression.Property(x, propertyName);
		var equal = Expression.Equal(propertyExpression, Expression.Constant(community));
		expression = expression == null ? equal : Expression.Or(expression, equal);
	}

	if (expression == null)
		return list;

	var lamda = Expression.Lambda<Func<T, bool>>(expression, x);
	return self.Where(lamda);
}

var communities = new []{ "Community 1", "Community 2", "Community 3" };
var result = activities.Where(x => x.Community, @in: communities);

Linq rules!!

Categories: C# Tags: , , , ,

Magiq to Entities – An update

May 7, 2011 2 comments

The past days I’ve been working on making Magiq work with Entity Framework.

First I tried to work with the MetadataWorkspace and I gave up, ’cause its really impossible to get the mapping information. Luckily, I found Linq to Edmx project who does exactly what I needed.

Then I had some troubles working with the Queryables generated by the ObjectSets. Basically, the expression generated calls methods that doesn’t work and are there only to give information in the expression. So the expression is not something you can compile and execute. As big part of Magiq is to manipulate expression trees, that was a really big problem. I needed to figure out how to change the source queryable (I mean, the queryable where all the methods are applied to) to a simple ObjectSet. Besides it works now, I’m still working to get to a nicer way (you don’t want to know what I have done to make it work…).

Since I changed the insert API from having the new item expression (the new{…}) outside to have it as a select, I had to break the query in two, the select and the “rest”. Ok, that gave me more headaches :).

But the biggest problem was when Entity Framework started to change the order of the columns in the select (and add new columns). Let me explain how Linq to Sql works:

If you do this:

items.Where( ... ).Select( x => new { A = x.Prop1, B = x.Prop2, C = x.Prop2 /*again*/ });

Linq to sql transate it to:

SELECT prop1, prop2, prop2 FROM items WHERE ...

But Entity Framework removes the repeated columns and maybe reorders them, giving you something like:

SELECT prop2, prop1 FROM items WHERE ...

You don’t have any idea of the reflection tricks I had to make to get those property-select columns mapping.

But well, those are not bad news at all. I mean I could work around them and I can say Magiq now supports Entity Framework (with a few restrictions). Those are:

  • Only Table per class hierarchy inheritance is supported. I’m currently working on the Table per concrete class and Table per type strategies
  • Only mapped associations are supported. This means associations based on foreign keys are not (yet).
  • Only mapped POCOs are supported. This means Self Tracking entities and Code First are not (yet).

Keep in touch for the updates ๐Ÿ™‚

Weak Dictionaries

April 25, 2011 1 comment

Suppose you need a complex/slow process for generating something and you want to cache it. But you don’t know if that something will be used a lot of just a few times. If it is the last case, you don’t care executing again the process, but it’s different if it’s accessed several times.

WeakDictionary to the rescue!

This dictionary, basically, maintains each value in a class that could reference it as a weakreference if it wasn’t accessed often and if the amount of items is bigger than a threshold defined:

var d = new WeakDictionary<int,SomeClass>(3);
d.Add(1, new SomeClass());
d.Add(2, new SomeClass());
d.Add(3, new SomeClass());

//We use the values...
var bla = d[1];
var bla1 = d[1];
var bla2 = d[1];
var bla3 = d[2];
var bla4 = d[2];
var bla5 = d[3];

//When we try to add an item and we are passing the threshold, it will weak the less used reference
d.Add(4, new SomeClass());

d[3] value is now maintained with a weak reference. If it’s used before it’s garbage-collected, it will be alive again and d[2] will be the “weak one”.

You can download the code here.

Categories: C# Tags: ,

MemoDb: Cascades and Collections support

February 10, 2011 Leave a comment

I’ve been implementing some new features and I think it’s ready for an alpha release. I’ll be uploading the files in codeplex.

To follow the MemoDb posts saga:

Now, MemoDb supports:

  • Delete
  • Collections
  • EntityRef (for LinqToSql support)
  • Cascade inserts
  • Cascade delete on collections children (aka all-delete-orphans)

Delete
Pretty simple, it let you delete objects:

using (var s = memo.CreateSession())
{
	var city= s.GetById<City>(1);
	s.Delete(city);
	s.Flush();
}

Cascade Inserts
You can configure MemoDb to insert new references by default:

var memo = new Memo(insertByCascadeByDefault: true)

Or you can specify the behaviour just for one relationship:

 var memo = new Memo()
           .Map<City>(c => c.CasacadeInsert(x => x.Country))
           .Map<Country>();

Cascade Delete Orphans
You can configure MemoDb to delete collections children by cascade when the parent object is deleted by default:

var memo = new Memo(deleteOrphansByCascadeByDefault: true)

Or you can specify the behaviour just for one collection:

 var memo = new Memo()
           .Map<City>()
           .Map<Country>(c => c.CasacadeDeleteOrphans(x => x.Cities));

MemoDb: Auto assign id support

February 4, 2011 Leave a comment

MemoDb is a in-memory-linq-database useful for mocking linq repositories in unit testing. You can track the previous posts:

Today I will talk about the generation of ids for new entities. As MemoDb stands for mocking real linq orms and, generally, the underlying databases auto assign the ids.

var memo = new Memo()
     .Map<MyEntity>(x=>x.Id(x => x.Id, autoAssign: true));

By now, MemoDb supports:

  • Int32: increments the last id.
  • Int64: increments the last id.
  • Guid: Generates a new Guid.

If you need another strategy or to map another id type, you can specify the strategy as a delegate:

var memo = new Memo()
     .Map<MyEntity>(x=>x.Id(x => x.Id, last => last + 10));

In the example above, the generation is made adding 10 to the last id assigned.
By default, MemoDb will assign the ids when the object is inserted. You can override this behavior by configuration:

var memo = new Memo(assignIdMode: AssignIdMode.OnFlush)
     .Map<MyEntity>();

Introduction to MemoDb

February 3, 2011 Leave a comment

I’m working on an internal framework on the company I work (it will be open source soon I expect to post a lot in the future about it) that needs the ability of mocking a repository with a memory database. Since this repository works with Linq, an implementation with a List inside was enough.
The time passed and we realize that it will be really usefull to have transactions in that repository (ok, not so usefull, but at least funny ๐Ÿ™‚ ). So I started to work on MemoDb.
The source code of the first version is in http://memodb.codeplex.com.

Let’s show some examples:

var memo = new Memo()
				.Map<City>();


using (var s = memo.CreateSession())
{
	s.Insert(new City
				 {
					 Id = 1,
					 Name = "Buenos Aires"
				 });
	s.Insert(new City
				 {
					 Id = 2,
					 Name = "New York"
				 });
	s.Insert(new City
				 {
					 Id = 3,
					 Name = "Montevideo"
				 });
	s.Insert(new City
				 {
					 Id = 4,
					 Name = "Bogotรก"
				 });
	s.Flush();
	s.Insert(new City
				 {
					 Id = 5,
					 Name = "Bangkok"
				 });

}

using (var s = memo.CreateSession())
{
	var cities = s.Query<City>().Where(x => x.Name.StartsWith("B"));

	Assert.AreEqual(2, cities.Count());
}

Note that it doesn’t store Bankgok.

var memo = new Memo()
				.Map<City>();

var buenosAires = new City
{
	Id = 1,
	Name = "Buenos Aires"
};
using (var s = memo.CreateSession())
{
	s.Insert(buenosAires);
	s.Flush();
}

City buenosAires2;

using (var s = memo.CreateSession())
{
	var test = s.GetById<City>(buenosAires.Id);
	test.Name = "Bs As"; //Not flushed!
}

using (var s = memo.CreateSession())
{
	buenosAires2 = s.GetById<City>(buenosAires.Id);
}

Assert.AreEqual("Buenos Aires", buenosAires2.Name);

Right now it supports:

  • Inserts
  • Updates of dirty objects
  • Many-to-one relationships
  • Queries

Next steps:

  • Delete
  • Collection management
  • Id generation strategies
  • Cascade

In future posts I will be talking about the implementation details.

Categories: C#, MemoDb Tags: , , , ,