Landman Code Exploring my outer regions of coding.

A blog about C#, Delphi, assembler and general developer stuff.

Landman Code Exploring my outer regions of coding.

A blog about C#, Delphi, assembler and general developer stuff.

Protection your EntityCollections from outside abuse by wrapping them as IEnumerable

In the previous post I introduced a wrapping extension for Entity Framework, and used enumerations as example, but there are is one more powerful feature which this offers, you can hide your internal details from outside users.

Why would for instance some external piece of code need to have access to the EntityCollection.Remove method when the only one with access should be the entity itself or perhaps the aggregate root. Entity Framework forces you to use EntityCollections for relations were most of the times a IEnumerable would be a much better abstraction.

In our projects we have code such as the following to wrap these EntityCollections:

public partial class Order
{
	public IEnumerable<OrderDetail> Details
	{
		get
		{
			// Lazy loading in EF1
			if (!DbDetails.IsLoaded && !(this.IsDetached() || this.IsNew()))
				DbDetails.Load();
			return DbDetails;
		}
	}
}

Using this collection in any kind of query will trigger NotSupportedException from Entity Framework the same as the previous post. But when using the EFWrappableFields extension the queries are also translated to use the DbDetails when translating to SQL and thereby solves the problem and provides the possibility of hiding the real EntityCollection behind a safe IEnumerable interface.

So have fun with this extension, and when you can improve the code, please fork me at Github.

Adding support for enum properties on your entities in Entity Framework

While Entity Frameworks is a reasonably nice ORM and the push of Microsoft behind a technology sure helps adoption from the corporate people, there are some seriously annoying limitations. The heavy dependencies can be abstracted away by (ab)using interfaces and other object oriented constructs. But some limitations are deeply nested within the assumptions of Entity Framework and are hard to work around.

One that has annoyed me very much was that (before POCO support) only certain types of properties are allowed. Using any other property type gives annoying NotSupportedExceptions, or the designer does not allow it. This became very apparent with enumerations, there are multiple use cases for enumerations in a data model and should cause no real harm to the queries to cast a integer back and forth to a enum, but EF only likes scalar type in the expressions to be converted to SQL. You'll enjoy messages such as "LINQ to Entities only supports casting Entity Data Model primitive types.". While I can understand that supporting enumerations is apparently very hard to solve (for the EF team that is), they could have added a way to offer wrapping the access to these fields so the external users of the entities do not have to share intimate internal details.

Assuming you have a Order entity and you hide the Status field in your entity behdind DbStatus and create a custom property which casts the Integer to a enum and back. As follows:

public enum OrderState
{
	Unknown = 0,
	InProcess = 1,
	Approved = 2,
	Backordered = 3,
	Rejected = 4,
	Shipped = 5,
	Cancelled = 6
}

public partial class Order
{
	public OrderState Status
	{
		get { return (OrderState)DbStatus; }
		set { DbStatus = (int)value; }
	}
}

If you would then write a Query such as:

var approvedOrders = new EFTestDatabaseEntities().Orders.Where(o => o.Status == OrderState.Approved).ToList();

You would get a nice exception:

System.NotSupportedException : The specified type member 'Status' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

So I created an extension which adds wrapping support to Entity Framework 1 (and 4), this wrapping offers a way to support these queries by changing the actual query just before EF starts translating the expression tree to SQL. This in itself is not that big of a challenge, but Entity Framework being closed and inextensible as it is, it took some time (and a StackOverflow question) to find the right place to inject this logic.

After using it for a few projects I thought I should share this with the community, so I created a Github project to host the source code, and share it with the rest of the world suffering from Entity Framework. The change required to be able to wrap is that the original ObjectQuery must be replaced with a instance of WrappedFieldsObjectQuery containing the original ObjectQuery. When your using a pattern such as repository, this change should only have to be in one file in perhaps a few places.

The previous example than becomes:

var approvedOrders = new WrappedFieldsObjectQuery<Order>(new EFTestDatabaseEntities().Orders)
	.Where(o => o.Status == OrderState.Approved).ToList();

And will now run and replace the Status field in the Expression tree to the DbStatus field in the model just before the translation to SQL. The way this works is by convention, the WrappedFieldsObjectQuery tries to find for every property used if there is an property with the "Db" perfix and than replaces the reference with that one. So if the wrapped field was named WrappedStatus, this wouldn't have worked, but it avoids any clutter on the Entity site with either attributes or interfaces.

You can get the source here. (you can also download compiled dll's for EF 1 and EF 4 from Github) Both Entity Framework 1 and Entity Framework 4 are supported, but for EF4 I've only tested it with the generate model from database. I added EF4 support while I haven't used it yet in any project, but I will investigate soon if EF4 offers better ways to do this, and if POCO even needs this kind of extension.

ps. you can also use this wrapper to protect your relations (such as collections) to other entities, see my other post describing this.