Monthly Archives: June 2009

SaveChanges is virtual in EF4

I don’t know whether I just noticed this too late, but the SaveChanges method in upcoming EF4 is virtual. This is a great small change.

You can generate (if you’re using T4 templates for generating) your own SaveChanges method and do some work there. Well, before actions can be done using SavingChanges event, i.e. validation like in this example. But for after actions, there’s no SavedChanges event (neither in EF4). Hence adding some code into this method is very handy. For example logging actions performed is super easy.

This small change opens up new ways of thinking about SaveChanges usage.

The method also have new SaveOptions parameter. As it’s enum we can expect adding more options in future versions.

Entity Framework v4 and Firebird

The Beta 1 of Entity Framework v4 (confused with versions?) is out for a while and you may be tempted to check the new features comming. And why not with Firebird.

Good news is, that there’s no breaking change right now I’m aware of. Hence you can easily jump into VS2010, install DDEX and test it. Of course, some new features are now not fully functioning as it’s beta and/or because it’s not nailed down for provider writers (i.e. DDL script generation). But as far as something will be ready, I’ll try my best to get it into Firebird’s provider.

On the other hand, even the new singularize/pluralize function is nice and works with all databases, you still get all names in uppercase, only the added suffixes are lowercase. And that looks even more weird. You can fix it yourself manually or let computer do the work, but still wondering why there isn’t any option to fix this (as uppercased name is default when not quoted according to SQL standard).

Anyway, if you found any problems with EF4, let me know.

Scope of pregenerated views

Pregenerating views can speed up startup time of you application. You may find more info in my previous post about it. On the other hand, setting up this for all developers or i.e. build machine can be tricky. Thus it may be worth to think whether it’s for you or not.

One reason not to pregenerate these views (besides laziness ;) ) could be, that your application is long running (i.e. windows service or ASP.NET app (I’m not IIS and ASP.NET guru so I hope this is also the case)) and if these views would be cached in smart way, application will be benefit from it even without pregenerating.

Good news. These bi-directional views are cached per appdomain. So if you don’t care about startup time and your application is long running (in one appdomain) you don’t have to care about setting up all the stuff described in the article.

Vista a vypínání grafika-3D-čehosi

Vista mi jaksi vypíná grafika-3D-cosi (zajímavé, že to začalo zlobit až po instalaci systému s integrovaným SP1). Takže se minimalizace okna, scrollování nebo třeba Alt-Tab trošku zasekávalo. Hlavně Alt-Tab mě štvalo, protože trvalo relativně dlouho, než se zobrazilo. Po dlouhé snaze vyřešit to systémově, jsem přešel na “programátorské” řešení.

Vzal jsem první WPF sample s pěknou 3D animací a udělal z toho aplikaci, bez tlačítka na taskbaru. A překvapivě to skvěle funguje. Aplikace mi běží na pozadí a jsem spokojenej.

Zde je vidět desktop s běžící aplikací:

MetadataWorkspace in Entity Framework

A lot of people get used to understand the ObjectStateManager class. Yep, it’s the place where all the change tracking magic happens. But there’s also one other place that’s interesting. It’s MetadataWorkspace. With this class’ properties and methods you can find almost everything about stuff in your model, in runtime.

The information inside MetadataWorkspace is among others organizes into so-called spaces (DataSpace enum). Probably CSpace and SSpace are the most used. The CSpace contains stuff you have in your conceptual model (what you see in designer) and SSpace contains stuff from store model, so the database “structure”.

The items in MetadataWorkspace can be anything from the Metadata Type Hierarchy (definitely look at this link) starting with GlobalItem. This contains i.e. EntityType, ComplexType or EdmFunction. These types inside are containing a lot of other useful information. Thus when you want to show i.e. all tables and primary keys for these tables you can use (don’t forgot to first, for example, query for one record to load metadata or use this trick):

MetadataWorkspace mw = ent.MetadataWorkspace;
var items = mw.GetItems<EntityType>(DataSpace.SSpace);
foreach (var i in items)
{
    Console.WriteLine("Table Name: {0}", i.Name);
    Console.WriteLine("Keys:");
    foreach (var key in i.KeyMembers)
    {
        Console.WriteLine("t {0} ({1})", key.Name, key.TypeUsage.EdmType.FullName);
    }
}

I’m first asking for all entity types from store space, which gives us all tables there. Then I’m simply inspecting the properties to get some useful info – first the name of table and then all key members reading name and type (EdmType). Also the MetadataProperties is definitely worth looking (see below). It’s just a tip of an iceberg, and that was not difficult. You can literally get any information you’ve ever seen in your model.

And not only what you’ve seen in your model directly. For instance, the provider may expose some store specific functions you can use in ESQL queries. So the code:

var functions = mw.GetItems<EdmFunction>(DataSpace.SSpace);
foreach (EdmFunction function in functions.Where(f => (bool)f.MetadataProperties["BuiltInAttribute"].Value))
{
    Console.WriteLine(function.FullName);
}

Gives you all of these functions. If you remove the condition you’ll get all functions, including stored procedures of user defined functions. Wanna parameters of these functions? No problem, it’s there. Just check Parameters property.

And that’s only the SSpace. The conceptual part of model is described there too. To see how much is the model interconnected (i.e. to consider pregenerating views) simply run:

var entities = mw.GetItems<EntityType>(DataSpace.CSpace);
foreach (var entity in entities)
{
    Console.WriteLine("Table Name: {0}", entity.Name);
    Console.WriteLine("Navigation Properties#: {0}", entity.NavigationProperties.Count);
}

Interesting may be also the object model aka objects created from conceptual model. Although I can continue with some more or less useful examples – to see all to posibilities (and also hit the accessibility limitations), try it yourself. And if you stuck, feel free to ask (here or in forums).