Posts Tagged Entity Framework

Running queries in parallel with Entity Framework (and not only with it)

From time to time I have to run two or more queries that I know will always be two or more – like some first/skip records and also total count. If you write it as two queries and execute, that means two round trips to database. Although it may not matter if the network latency is very small, why not to challenge myself and try to find some workarounds.

Sure you can create some stored procedures and get the data back from these, but I was thinking about more LINQ to Entitiesish way. I recalled a way I one time used inside one project. Although it was done in pure SQL, it, as it turned out, works, kind of, for LINQ to Entities as well.

The idea is using “one row table” and put the queries as columns. Let me demonstrate:

select
  (select foo, bar from table1 where ...),
  (select baz, foo from table2 where ...)
from OneRowTable;

Where the OneRowTable can be specially created table or i.e. for Firebird RDB$DATABASE or for Oracle Database dual. It isn’t the nicest SQL (and also challenges optimizer), but works. In columns as queries you can put anything you want as long as it is syntactically correct.

OK, what about the Entity Framework or LINQ to Entities respectively. I created the “one row table” first:

create table OneRowTable(x bit primary key);
insert into OneRowTable values (0);

The table needs to have the primary key to be able to import it into entity model, the datatype doesn’t matter (I was using MS SQL, hence the bit).

What about the queries? Similar approach:

var allinone = context.OneRowTable.Select(_ => new
{
	AData = context.a.Where(a => a.x.HasValue && a.x.Value > 10).Select(a => new { A1 = a.id, A2 = a.id * 2 }),
	BData = context.b.Where(b => b.id < 999).Select(b => new { B1 = b.id, B2 = b.y }),
});
string query = (allinone as ObjectQuery).ToTraceString();
var data = allinone.First();
var adata = data.AData;
var bdata = data.BData;

The a and b are my testing tables. You can check there’s only one query executed. Encapsulating this into some method is only piece of cake.

And how the query looks like? Well for my MS SQL test:

SELECT
[UnionAll1].[x] AS [C1],
[UnionAll1].[C2] AS [C2],
[UnionAll1].[C1] AS [C3],
[UnionAll1].[id] AS [C4],
[UnionAll1].[id1] AS [C5],
[UnionAll1].[C3] AS [C6],
[UnionAll1].[C4] AS [C7],
[UnionAll1].[C5] AS [C8],
[UnionAll1].[C6] AS [C9]
FROM  (SELECT
	[Project1].[C2] AS [C1],
	[Extent1].[x] AS [x],
	1 AS [C2],
	[Project1].[id] AS [id],
	[Project1].[id] AS [id1],
	[Project1].[C1] AS [C3],
	CAST(NULL AS int) AS [C4],
	CAST(NULL AS int) AS [C5],
	CAST(NULL AS varchar(1)) AS [C6]
	FROM  [dbo].[OneRowTable] AS [Extent1]
	LEFT OUTER JOIN  (SELECT
		[Extent2].[id] AS [id],
		[Extent2].[id] * 2 AS [C1],
		1 AS [C2]
		FROM [dbo].[a] AS [Extent2]
		WHERE ([Extent2].[x] IS NOT NULL) AND ([Extent2].[x] > 10) ) AS [Project1] ON 1 = 1
UNION ALL
	SELECT
	2 AS [C1],
	[Extent3].[x] AS [x],
	[Extent4].[id] AS [id],
	CAST(NULL AS int) AS [C2],
	CAST(NULL AS int) AS [C3],
	CAST(NULL AS int) AS [C4],
	[Extent4].[id] AS [id1],
	[Extent4].[id] AS [id2],
	[Extent4].[y] AS [y]
	FROM  [dbo].[OneRowTable] AS [Extent3]
	CROSS JOIN [dbo].[b] AS [Extent4]
	WHERE [Extent4].[id] < 999) AS [UnionAll1]
ORDER BY [UnionAll1].[x] ASC, [UnionAll1].[C1] ASC

Not exactly the original shape. The translator took another way creating two one row results and using union all to get it into one query. Except this, the query is in general the same (the explicit joins are as result same as the subselects, though little bit more confusing in this case).

Again, this isn’t general purpose way of doing it and may result in worse performance than running queries separately and I would recommend using it only after careful testing and on controlled limited set of queries.

Tags: , , , , , ,

Complex types and stored procedures – 2nd edition

Some time ago I was writing about not supported scenario when you have entity with complex type and you want to map result of stored procedure to this entity. I couldn’t believe that this, from my point of view fairly common, scenario will not be supported in designer in RTM.

Right now I’m running RC of Visual Studio 2010 (the development probably in feature freeze mode) and the limitation is still there. :( Jeff Derstadt was not lying. Although Zeeshan Hirani in forum said, he was able to do it manually, it’s uncomfortable. Same as complex types in EFv1.

Looks like complex types, sadly, are still not first class citizens for designer.

Tags: ,

Spatial data and Entity Framework – from real world usage

Julie Lerman created a post about spatial data usage in Entity Framework. Her conclusions are correct. But because from last three projects I did on Entity Framework two of them are working with spatial data (every customer wants a Google Maps or Bing Maps on website, it’s like cup holders in cars) I would like share my solution as well some ideas behind why I used this approach.

First and foremost Entity Framework doesn’t support spatial data now. So you have to create some workaround. The idea getting the data through blob is exactly what I created. In my tables where I need to save some coordinates (it’s mainly a point) I create simple column with this data type – I consider this clean initial work better, because maybe sometimes/somewhere/somebody will work with this structures so to have it clean. Then for the workaround I add XXX_bin column where I’ll store the binary representation of spatial data and use it for Entity Framework. Something like this:

[Location] geography Default geography::STGeomFromText('POINT EMPTY', 4326) NOT NULL,
[Location_bin] Varbinary(max) NOT NULL,

Because I’m working only through Entity Framework I need to update the Location automatically as there might be (and are) indices or other stuff working with it. To make it transparent I’m using insert or update trigger:

if (update(Location_bin))
begin
  update %tablename% set
    Location = geography::STGeomFromWKB(Location_bin, 4326)
  where
     ID in (select ID from inserted);
end

If you expect somebody updating the Location column directly too, you need to create another trigger and make sure you’ll not end up in infinite loop.

To support the – in my case – points for UI developers I create in every entity computed property turning Location_bin into my LatLong struct. This struct is using Microsoft.SqlServer.Types namespace.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Types;

namespace FooBar
{
    public struct LatLong
    {
        public double Lat { get; set; }
        public double Long { get; set; }

      public static LatLong FromSqlBytes(byte[] bytes)
      {
        SqlGeography g = SqlGeography.STGeomFromWKB(new SqlBytes(bytes), 4326);
        return new LatLong { Lat = g.Lat.Value, Long = g.Long.Value };
      }

      public byte[] ToSqlBytes()
      {
        return SqlGeography.Point(this.Lat, this.Long, 4326).STAsBinary().Buffer;
      }
    }
}
public LatLong Location
{
  get
  {
    return LatLong.FromSqlBytes(this.Location_bin);
  }
  set
  {
    this.Location_bin = value.ToSqlBytes();
  }
}

This creates almost seamless support for other developers when using spatial data in Entity Framework – inserting, updating, deleting all works without notice from others (if you’re not looking into internal implementation).

There are only two problems, both solvable.

First one is that developer cannot filter/sort/… using Location property. This isn’t probably a big problem. As (s)he doesn’t have spatial methods (like i.e. Distance) available, so the queries will not make sense. Which brings me to the other problem and that’s the querying. With EFv1 I created stored procedures for these queries and returned data through these. Same works for EFv4. If you have strict set of results you need, this is probably easiest solution. The other one, working in EFv4 is LINQ function imports via EdmFunction attribute. For computations I’m going to use I create function in T-SQL doing the work and I import it into my solution thru above noted attribute. The simple Distance method may look like:

create function Distance
(
  @Location_bin1 varbinary(max),
  @Location_bin2 varbinary(max)
)
returns int
as
begin
  return geography::STGeomFromWKB(@Location_bin1, 4326).STDistance(geography::STGeomFromWKB(@Location_bin2, 4326));
end

And

[EdmFunction("model.Store", "Distance")]
internal static int Distance(this byte[] location1, byte[] location2)
{
  throw new NotSupportedException();
}

Sure, when calling this function for a big resultsets it may be a performance bottleneck (I recommend doing there as much work as possible, even at the price of more functions doing similar stuff, to not create a deep function calls.), but with additional filters it works well.

protected IQueryable<Something> SomethingInDistance(LatLong point, int distance)
{
  byte[] spatialData = point.ToSqlBytes();
  return this.Somethings.Where(o => o.Location_bin.Distance(spatialData) < distance);
}

Another way could be to create a view (if you know the parameters in advance) and do explicit join (table/entityset <> view/entityset) in EF. Or do the filtering on client (if reasonably small). And I’m sure I’ll find other ways how to get the data you want back, simply choose what fits your needs best.

Although it may look like a lot of work, it isn’t. In fact you’re pretty fast (there’s a high level of reusability) if you know what to do (and after one implementation you will).

Tags: , , , , ,

SQL command when inserting M:N association with identity columns in the underlying table

Today I uncovered a magic command from Entity Framework v4 when you create M:N association and the underlying table is defined with both columns as identity (you insert there). I don’t what’s it good for, as this table in fact only stores the two IDs to connect other tables. But somebody may build some logic on identity there, sure.

When I first saw the command, I was completely stunned. I had no idea what’s going on there and whether I see there one or more commands. You can have fun too:

declare @generated_keys table([ID_A] int, [ID_B] int)
insert [dbo].[A_B]
output inserted.[ID_A], inserted.[ID_B] into @generated_keys
default values
select t.[ID_A], t.[ID_B]
from @generated_keys as g join [dbo].[A_B] as t on g.[ID_A] = t.[ID_A] and g.[ID_B] = t.[ID_B]
where @@ROWCOUNT > 0

As an old school guy I was first looking for semicolons and then later tried to decode it by “parsing” the content.

Isn’t it nice… :)

Tags: , ,

EdmGen2 with EFv4

EdmGen2 is a nice tool. Especially if you know EdmGen you may find it useful. I.e. you may speed up the start of you application by pregenerating views directly from EDMX file.

Unfortunately if you try to use it with EFv4 it will crash. But we have sources, why not to fix the problem? And that’s what I did.

First problem was with new namespaces the EFv4 EDMX file has. The new ones are:

static string csdlNamespace = "http://schemas.microsoft.com/ado/2008/09/edm";
static string ssdlNamespace = "http://schemas.microsoft.com/ado/2009/02/edm/ssdl";
static string mslNamespace = "http://schemas.microsoft.com/ado/2008/09/mapping/cs";

The next step is to switch the project to target .NET Framework 4, you can do it in project options. And finally check whether the references, especially System.Data.Entity.Design, where the interesting objects are, are pointing to “4.0.0.0 versions” and correct if needed.

Done. Build and use. And if you don’t wanna to have it without work, grab this file with all changes already done.

Tags: ,

Complex types and stored procedures

I like the idea of complex type. Sadly the designer didn’t supported complex types in EFv1/VS2008, although you could use it manually editing the model (it’s just a XML file). The designer in EFv2/VS2010 supports complex types (and you can use it also with EFv1, see this) hence it’s time to start really using these.

Unfortunately nothing is perfect. As far as you don’t wanna map some stored procedure result to collection of entities, then the designer will tell you, that it’s not supported. :( And Jeff Derstadt pointed in forum that this limitation will not be solved in RTM.

I’m using EFv4 in my current project and thanks to ability to map functions directly to LINQ functions via EdmFunction attribute I was able to to a lot of work via functions and queries created by EF itself. But I always feel a little bug in my head saying “What if you’ll need it later?”. Sure I can redo all back into direct properties, but if it’s close to the end of the project it’s pretty expensive to do it.

What a pity, I see complex types as a good concept, but I’m too careful to close myself the path with SPs.

Tags: ,

Be careful with “not” conditions and nulls in LINQ when querying databases

Today I seen a code with good chance of hard to find mysterious bugs. Let’s start with database table structure we’re going to use for demonstration.

create table NullTest(id int primary key, b bit);

insert into NullTest values (0, 1);
insert into NullTest values (1, 0);
insert into NullTest values (2, null);

If you now try to query this table via LINQ (i.e. LINQ to Entities) you may get surprising results.

foreach (var item in ent.NullTests.Where(x => x.b != true))
{
	Console.WriteLine(string.Format("ID: {0} \t B: {1}", item.id, item.b));
}
Console.WriteLine("===");
foreach (var item in ent.NullTests.AsEnumerable().Where(x => x.b != true))
{
	Console.WriteLine(string.Format("ID: {0} \t B: {1}", item.id, item.b));
}

If you run this code, you’ll get different results.

ID: 1    B: False
===
ID: 1    B: False
ID: 2    B:

What happened? Is the database engine doing something wrong? Or is there a bug in LINQ? Neither of those. In fact both results are correct. The second one (evaluated in .NET on client) is obvious why it’s as is. But what happened in processing of first one (evaluated on database side)? The devil is in NULL logic. Every operation with NULL results in NULL or false if it’s a boolean operation. And this exactly explains the inconsistent result. In .NET null != true is true but in databases it’s false (because of the NULL rules described above).

Thus if you’re writing LINQ query for database, although the impedance mismatch should be hidden from you when using LINQ, you need to take into account different NULL handling in database engines and in .NET (or any common programming language).

Remember the DBNull.Value? That was explicit solution for this “problem”.

Tags: , ,

Mysterious problem when fetching data

Sometimes you’re talking about something on trainings and conferences and … and you simply forgot about it when you use it – it’s like being able to think in A > B way but not B > A.

This time it’s about views in Entity Framework. If you add a view into your model, it’s likely it will have a wrong key set up. Or maybe it’ll be missing. And because if two records have same EntityKey, they are considered same, also skipping the very expensive materialization. I added one view into my model and didn’t check the key. It was working fine, until last week, when the application started behave “differently”. I checked the database and view was providing proper data. Fetching was just reading from this view, no other processing. After some serious debugging and getting wrong data, in my case all records had same values as the first one. When I switched the projection it was good. I started to think about blaming EF. And I was wrong, sorry guys in EF team. The reason was, as you might guess, wrong key setted up. My view has a key composed from three columns, but only one was used. This caused the EF during the materialization to skip other rows, because the first column was same, thus getting wrong results. Fixing the key solved the problem immediately. It’s more embarrassing because if you look into the XML file, there’s comment telling you to check the key, because the inferred one can be wrong.

Anyway, now I know also the B > A way, which is even better as it was my personal experience.

Tags:

Comparing date only in EF

From time to time you may need to compare only date part of datetime/timestamp field in your database i.e. for filtering. In EFv1 this is a little bit problem, in EFv4 (now beta 2) better.

Let’s start with EFv1. If you try to write something like this:

.Where(x => x.DateTimeColumn.Date == DateTime.Today)

You’ll end up with nice exception. Simply EF is not able to translate it. To solve this problem I created handy (for me) method, that will do simply expansion comparing Day, Month, Year, so you don’t have to write it over and over again.

public static Expression<Func<TElement, bool>> DateEquals<TElement>(Expression<Func<TElement, DateTime>> valueSelector, DateTime dt)
{
	if (valueSelector == null)
		throw new ArgumentException("valueSelector");

	ParameterExpression p = valueSelector.Parameters.Single();

	Expression ex = Expression.And(
		Expression.Equal(
			Expression.MakeMemberAccess(valueSelector.Body, typeof(DateTime).GetMember("Day").Single()),
			Expression.Constant(dt.Day)
			),
		Expression.And(
			Expression.Equal(
				Expression.MakeMemberAccess(valueSelector.Body, typeof(DateTime).GetMember("Month").Single()),
				Expression.Constant(dt.Month)
				),
			Expression.Equal(
				Expression.MakeMemberAccess(valueSelector.Body, typeof(DateTime).GetMember("Year").Single()),
				Expression.Constant(dt.Year)
				)
			)
		);
	return Expression.Lambda<Func<TElement, bool>>(ex, p);
}

So you can write i.e.:

.Where(Ext.DateEquals<DateTimeEntity>(x => x.DateTimeColumn, DateTime.Today.AddDays(-20)))

One modification I have in my head, is to extend it to support comparing two columns in database. But that shouldn’t be hard.

On the other hand, EFv4 contains couple of new canonical functions, for datetime/timestamp as well. One that’s useful for this case is TruncateTime, also exported for LINQ usage with EdmFunctionAttribute. With it, you can write queries little bit easier. Still not directly .Date, but i.e.:

.Where(x => EntityFunctions.TruncateTime(x.DateTimeColumn) == DateTime.Today)

Comparing two columns is available too. Sure, your provider needs to support this new function, but that should be no problem for all provider writers.

Maybe the future EF improvement could be to support .Date for translation too. ;)

Tags: , ,

IsLoaded and EntityKey

Today I discovered behavior of Entity Framework that is completely logic, but may surprise you, as it surprised me. Simply consider two entities with 1-N relationship. If you’re loading the “N-entity”, you know, whether the “1-part” is in database, because the foreign key column has some value or is null. If it’s null and you’ll check the IsLoaded property of EntityReference<T> it will say true, even you didn’t call Load method. And it’s correct and smart, because you know that the value will be null (because of the null foreign key column).

But if you set the EntityKey of EntityReference<T> (because you’re kind of simulating (i.e. for performance reasons) creating the association thru FK in EFv1) and SaveChanges, even after this, the IsLoaded will be true, Value will be null, but it will not be correct from point of view in current time. Sure working with EntityKey directly isn’t the recommended way, unless you know what you’re doing. On the other hand, if the EF is smart enough to state, that the EntityReference<T> was loaded for this null case (even if not explicitly), maybe it should be smart to invalidate this state when something changes in EntityKey (and changes are saved into database).

What do you think? Is it true or should you expect and know this when playing with EntityKey (as you should be probably enough experienced when using EntityKey)?

Tags:

Entity Framework 4 – MS Fest 2009

Nová verze Entity Frameworku už pomalu klepe na dveře a proto není od věci podívat se, co nového nabídne. V rámci přednášky na MS Festu projdu největší změny a vylepšení. Rozhodně je na co se těšit – pokud již EF používáte, tak na ulehčení života a pokud ještě ne, tak na ještě větší lákadla jej použít. A vzhledem k plánované večerní akci bude prostor i pro kuloární diskuze, nejen o EF.

Tags: , , , , , , ,

Foreign keys in conceptual model in Entity Data Model

When I first heard about exposing foreign keys in conceptual model I was getting crazy. It’s the object world, you shouldn’t think this way, in a relational world. On the other hand, working purely in objects can be a pain, especially in web development, and performance problem. Sure, foreign keys can solve you some “problems” (and maybe add some) without tweaking the EntityKey or doing stub entities. Which is hard when dealing with POCO.

But is this a really way to go? Exchange cleanness for comfort.

I don’t know. I was doing the EntityKey magic, and it was magic, because it was not clean. Now I can do it easily, but. For POCO it’s harder, as there’s no EntityKey, but again, you have plain objects – why to deal with foreign keys? What if you move to some non-relational store?

But still one piece is left. The M:N association. Here I cannot use any foreign key, so it’s back to hacking or pure objects. And maybe this is the point. If creating some kind of comfort here for developers, why not to find some way for complete story? Wouldn’t it be nice?

Now I know (see how good is trying to write your own ideas). I don’t like the current concept of FKs. It’s too easy, and just too replicating behavior of relational world. But if there would have been some improvement for the other types of associations to cover all types in uniform way, I would vote for it with both my hands. Although still saying that it’s not nice but acceptable, as relational databases – it seems – will be with us for sure next couple of years.

Tags: ,

Implicit lazy loading on by default in EF4

The last beta (Beta 2) of Visual Studio 2010 with EF4 contains one “interesting” change. The implicit lazy loading is turned on by default. And I’m not sure I like it.

I can handle the fact, that there was a strong demand for it (as Julie pointed) and that for LINQ to SQL people or beginners this may be much easier. But from a database guy perspective this is hidden evil, especially if you’re not the only one developer in project. You don’t know when you’re hitting the database and maybe worse, everything seems to be working fine (all data are there), but it’s a performance problem when you deploy the application from local/test environment. And how surprising will it be, when the context will be gone.

Maybe I change my opinion after trying to work with it. But now, I’ll rather use eager loading or I’ll be explicit with my calls to database. To be on safe side. What do you think?

Tags:

FBCon 2009 München – .NET + Firebird will be there

Next Firebird conference is coming. This year in München, Germany. I’ve never been in München though it’s pretty close to Czech Rep. thus I’m looking forward.

You can find info about conference at firebird-conference.com. I’ll be speaking there too, hence if you’re interested in Firebird and .NET you should definitely come. Every day I have one session. I’ll be covering new (2.5+) protocol implementation in .NET client for Firebird 2.1, Entity Framework support (also new in 2.5) and finally you’ll see how to create Windows phone (formely PocketPC, …) application and accessing Firebird database.

And the conference will be also great place to meet people you know from list etc. and talk face to face about your Firebird related problems, challenges and solutions. If you have any specific need to show (related to my three sessions) feel free to drop line in comments.

Tags: , , , , , , ,

Přednáška ADO.NET Entity Framework – MFF UK, Praha

Pokud jste nestihli první pražskou nebo brněnskou přednášku, máte v Praze další šanci. 3.11.2009 (úterý) od 17:20 v rámci programátorských večerů na MFF UK.

Více info zde nebo zde, registrace na http://akce.altairis.cz.

Prezentace ke stažení.

Tags: , , , , , ,

Attaching non-detached entity in Entity Framework v4 doesn’t throw exception

While slowly digging into Beta 2 of EF4 I discovered new nice “feature”. In EF1, if you had code like this.

master[] data;
using (testovaciEntities ent = new testovaciEntities())
{
	data = ent.masters.ToArray();
}
using (testovaciEntities ent = new testovaciEntities())
{
	foreach (master item in data)
	{
		ent.Attach(item);
	}
}

It threw InvalidOperationException saying An entity object cannot be referenced by multiple instances of IEntityChangeTracker.. Right but I don’t have access to my previous context anymore. This behavior caused me a lot of headache and I created couple of hacks to workaround it. But the good news is that the code above works fine in EF4.

Neat! Together with other improvements I can get rid of my hacks and sleep well again. ;)

Tags:

Associations without foreign keys

Michal Bláha asked me, before my session when I stopped in his office, whether it’s possible to create associations in Entity Data Model without foreign keys in database, as he’s not using FKs, he’s enforcing referential integrity in application (yeah, if you’re transaction guy like I am, your brain is about to blow).

Well, it’s for sure possible. First we define some simple tables:

create table test_master(
  id int primary key,
  foo nvarchar(20) not null
);

create table test_detail(
  id int primary key,
  id_master int not null,
  bar nvarchar(20) not null
);

You see, no FK defined. Then you generate model from database, just next > next > finish style and you end up with:

Now the magic begins. :) Just kidding. First delete the id_master column from entity, it has nothing to do in conceptual model. Next create new association (right click in empty space in designer) and create it as 1-*. OK, we’re almost there. The last step, is to map the association. It’s mapped to test_detail: test_master.id to id_master and test_detail.id to id.

Now you can start querying the data across associations.

string s = context.test_master.Include("test_details").ToTraceString();

Easily done, isn’t it.

Tags:

What’s new in Entity Framework 4 Beta 2 and ADO.NET Data Services 4 Beta 2

Nice list at http://blogs.msdn.com/adonet/archive/2009/10/19/vs2010-and-net-framework-beta-2-announced.aspx.

Tags: , , , , ,

Multithreading with Entity Framework

From time to time I get a question about using ObjectContext from more than one thread. Because Entity Framework sits on top of ADO.NET, it’s obvious, it cannot be thread safe. So if you need to use n threads, use m (where m>=n) ObjectContexts. That’s the easy way. But what if you really need to share ObjectContext between threads?

The first fact is, that you cannot run more statements at a time, because it will sooner or later create mess in provider. So the solution is to carefully lock the usage. Not good for scaling, but you can do (almost) nothing with it.

Another basic issue is that with IQueryable (if you’re using LINQ) you don’t know, when the query gets actually executed. Until somebody calls for example ToArray, it’s just a definition/shape of the query. And when it gets executed, the code can be out of your method or out of the lock. For sure. The composition will be affected little bit. You can create a rule, that everything you’ll be exposing to UI (or any higher level) developers will be for instance List<T>. Then you will probably need to prepare significant amount of methods, for almost every data projection, selection, … they need. Good news is, that you can hide (make i.e. internal) the original methods, and nobody will screw up something.

Maybe better option is to create simple method taking complete query as parameter and returning the data i.e. as IEnumerable (simply saying, fetched from database). This is good, but everybody has to be attentive, using only this method (it will be generic, so it may look little weird using it with anonymous type, but works and you can find something about it looking for “cast by example” using your favourite search engine). As a good side-effect, you can add easily add i.e. logging of queries being sent to the database from application.

Stored procedures are executed immediately (are not composable), thus you can just create simple wrapper around it with lock. Easy.

The rest is  saving changes. The SaveChanges method is virtual in EFv4, so your own implementation with lock will be easy (and you can use T4 templates for ObjectContext to make the code with lock right from generator). In EFv1, the story is similar as with querying. Create separate method and tell everybody use only this one or swat the original over with your own using new keyword.

Last topic that’s in my head right now, is working with entities in code – changing properties (don’t forgot associations). If one entity will be edited in more than one thread, you may (or may not) confuse ObjectStateManager as the overlapping change tracking may kick in. To be on the safe side, I think avoiding this is best way – choose whatever you like for doing it (and take into account that one thread can be editing the entity and the other one refreshing it from store, for instance, so choose proper granularity of lock (or introduce some rules into your code/team ;) )).

I don’t know whether I cover all main basic stuff you can do with EF as I’m writing it from top of my head, bare with me and feel free to comment. And be it as it is right now, if there’s 1% chance of being able to use separate ObjectContexts, do it. It will prevent you lot of headaches.

Tags: ,

Model Defined Function as a method on entity (or on type for store function)

Model Defined functions are new feature in EFv4. You simply define you function using EDM functions etc. in your model and then you can use it in your queries. With EdmFunction attribute you can also create stub function to use it in LINQ queries. That’s all great, and even itself makes life with Entity Framework easier.

But if you call it from LINQ (my favourite  way of querying), it’s kind of odd. You’re writing it as:

context.Persons2.Where(p => GetAge2(p) < 100);

And while I was preparing some demos for my presentation, there was a flash of idea in my head. “What if I define the function stub as extension method?”, I thought. Yes like:

[EdmFunction("testovaciModel", "GetAge2")]
static int GetAge2(this Persons2 p)
{
	throw new NotSupportedException();
}

This should work, right? It’s just sugar and the translation should work without complaining. And it really does. You can now write:

context.Persons2.Where(p => p.GetAge2() < 100)

Sweet! You can still keep these MDF method stubs in one place but use it in more natural syntax.

And by the way, it works for store functions as well (you’re just limited on types).

[EdmFunction("testovaciModel.Store", "GetAge")]
static int GetAge(this DateTime born)
{
	throw new NotSupportedException();
}
context.Persons2.Where(p => p.Born.GetAge() < 100)

I’m especially happy for store function exposed to LINQ. I’m using these in a reasonable amount in my databases and being able to filter using the function without wrapping the query into i.e. stored procedure or view is neat.

Tags: , ,