Monthly Archives: October 2008

Anonymous methods and Invoke – differences using MethodInvoker

OK, let’s start with some off topic paragraph. If you wanna to operate with some UI stuff from thread, you have to “push” the method processing into the UI thread. With .NET FW 2.0 and higher you can use SynchronizationContext class and let “the right” :) side to handle this. On the other hand, the classic (or older if you want) approach is to use Invoke method on some control, mainly Form (the problem here is, that the method have to know that’s called from thread – but it’s solvable too).

The problem with Invoke is, that when you put delegate as anonymous method there, it will not compile. Something like:

this.Invoke(delegate { button1.Text = DateTime.Now.ToLongTimeString(); });

So you can create your own delegates (“normal” delegates) and continue without any problem. But there’s a handy class called MethodInvoker. With it you can call anonymous methods without creating own delegates.

But you can find couple of articles, using two different syntax. One looks:

this.Invoke(new MethodInvoker(delegate { button1.Text = DateTime.Now.ToLongTimeString(); }));

and other:

this.Invoke((MethodInvoker)delegate { button1.Text = DateTime.Now.ToLongTimeString(); });

Both works like a charm. But is there any difference? Well to find out, you can do long thoughts, but the fastest way is take ildasm tool and grab compiled IL. Without long talking, look at results:

.method private hidebysig instance void  button1_Click(object sender,
                                                       class [mscorlib]System.EventArgs e) cil managed
{
  // Code size       21 (0x15)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldarg.0
  IL_0003:  ldftn      instance void WindowsFormsApplication1.Form1::'<button1_click>b__0'()
  IL_0009:  newobj     instance void [System.Windows.Forms]System.Windows.Forms.MethodInvoker::.ctor(object,
                                                                                                     native int)
  IL_000e:  call       instance object [System.Windows.Forms]System.Windows.Forms.Control::Invoke(class [mscorlib]System.Delegate)
  IL_0013:  pop
  IL_0014:  ret
} // end of method Form1::button1_Click
.method private hidebysig instance void  button1_Click(object sender,
                                                       class [mscorlib]System.EventArgs e) cil managed
{
  // Code size       21 (0x15)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldarg.0
  IL_0003:  ldftn      instance void WindowsFormsApplication1.Form1::'<button1_click>b__0'()
  IL_0009:  newobj     instance void [System.Windows.Forms]System.Windows.Forms.MethodInvoker::.ctor(object,
                                                                                                     native int)
  IL_000e:  call       instance object [System.Windows.Forms]System.Windows.Forms.Control::Invoke(class [mscorlib]System.Delegate)
  IL_0013:  pop
  IL_0014:  ret
} // end of method Form1::button1_Click

No doubts, the code is same. :)

So what to use? I think it’s question of personal preferences (and just to be consistent in whole code). OK, maybe the new ... makes little bit more sense, because the IL code contains constructor. But…

What’s your preference?

Timeout for wait transactions in FirebirdClient

I have implemented new feature available from FB2.0, it’s timeout for wait transaction. It’s a nice feature, ’cause you can specify how long do you wanna wait before getting deadlock error. Thanks also to Dmitry Yemanov for debug (that also revealed couple of new bugs; now already fixed).

The current implementation is pretty straightforward. If you don’t specify timeout then it’s not used (which is important for <FB2.0). Else (and you’re using wait transactions) is used. :) With this I redesigned a little bit the options for transactions. Now it’s more flexible and open for future improvements. Defining options for transaction is little bit different:

conn.BeginTransaction(new FbTransactionOptions() { TransactionBehavior = FbTransactionBehavior.Wait, WaitTimeout = 3 }))

Of course, you can create options object separately and put to method only variable. Changing old code to new one is just couple of rewriting, no new logic.

Enjoy!

Nullable types – what’s faster?

Today I was working with nullable types – short? for my instance. I was wondering what’s the fastest way of getting value and also testing whether the value is there.

1. HasValue vs. != null
Well test on my notebook on .NET FW 3.5 in VPC, optimization turned on shows that HasValue is faster. Roughly twice on my configuration. Also the IL code looks different.

2. Using Foo.Value vs. (short)Foo
Here I didn’t measured any difference. And the code is pretty much same. It’s not exhaustive testing (and you know – I believe only in stats I adulterated ;) ).

I did about 10 runs for each test and looked to IL (it’s fastest way to prove your idea is wrong or not).

What about you? Similar results?

How to use custom objects with associations in Entity Framework

Today I had some time and I spent it playing with associations mapping on custom objects. Adding new objects is easy. It’s what you already know. The only one new part is work with associations and navigation properties. But as always when you stuck you can generate dummy EDMX file and look at the result. :-)

You can start from scratch and create all classes and so on as in previous article. But I’ll start where I ended, it’s little bit faster.

First thing you have to create is new class, related to our Product class. I’ll create ProductSize class that will hold info about the size of product (don’t try to find something useful on this, it’s just a simple example). The class will contain only ID and Size property. You can take inspiration from previous article, it’s almost same. What you have to add is an IEntityWithRelationships interface implementation to both classes. It’s same for both. This interface forces you to implement RelationshipManager member.

RelationshipManager IEntityWithRelationships.RelationshipManager
{
  get
  {
    if (_relationships == null)
      _relationships = RelationshipManager.Create(this);
    
    return _relationships;
  }
}

Now you have to either edit CSDL, MSL and SSDL files by hand (if your night reading is some *.edmx file) or generate these again using EdmGen/EdmGen2 and remove any unnecessary lines. Also you can rename some items to match your needs and class members (i.e. if you have NavigationProperty one-to-many on one side would be probably plural and on other side singular). Good checkpoint after this is to run EdmGen with ValidateArtifacts mode to uncover any problems.

After this you have to modify class that you get in previous article from custom tool usage. You have to apply EdmRelationshipAttribute using the assembly prefix, because it has AttributeTargets.Assembly as usage. When you use custom tool, it will be generated for you. When first trying to do the mapping I forgot about it and I lost half an hour of my time. :-)

[assembly: EdmRelationship("CustomClasses_EDM", "FK_Products_ProductSizes", "ProductSizes", RelationshipMultiplicity.One, typeof(CustomClasses_EDM.ProductSize), "Products", RelationshipMultiplicity.Many, typeof(CustomClasses_EDM.Product))]

Now you only need to add navigation properties in your custom classes. Of course, you can add some properties to your ObjectContext class, similar to Products.

OK, first, apply EdmRelationshipNavigationProperty attribute to your navigation properties. For my Product object and ProductSize property it looks like this.

[EdmRelationshipNavigationProperty("CustomClasses_EDM", "FK_Products_ProductSizes", "ProductSizes")]

Let’s do the getter. You have to get RelationshipManager and use GetRelatedReference method. For my Products ⇒ ProductSizes direction you should end up with:

get
{
  return ((IEntityWithRelationships)(this)).
    RelationshipManager.
    GetRelatedReference<ProductSize>("CustomClasses_EDM.FK_Products_ProductSizes", "ProductSizes").Value;
}

For other direction use the GetRelatedCollection method and no Value is used. The setter for Products ⇒ ProductSizes direction is just about assigning value to Value. For ProductSizes ⇒ Products it’s little bit different. You have to use InitializeRelatedCollection method to set new value.

((IEntityWithRelationships)(this)).
  RelationshipManager.
  InitializeRelatedCollection<Product>("CustomClasses_EDM.FK_Products_ProductSizes", "Products", value);

And maybe it’s good idea to check for nulls, because it’s not allowed to put it there (again, just fine-tuning).

Now when you try to run the code like:

var q = from p in ctx.Products
         where p.ID < 200
         select p; 

foreach (Product p in q)
{
  Console.WriteLine(p.Name);
  Console.WriteLine("t" + p.ProductSize.Size);
}

You got exception. Yeah, lazy loading. You have to use, for example (Entity Framework Include with Func):

var q = from p in ctx.Products.Include("ProductSize")
         where p.ID < 200
         select p;

foreach (Product p in q)
{
  Console.WriteLine(p.Name);
  Console.WriteLine("t" + p.ProductSize.Size);
}

Using custom objects and associations with Entity Framework isn’t hard too. You generate three files from database, change it (which is maybe the hardest part – to match database to your objects) and small changes in objects. And you’re done.

Yet again, with POCO and persistence ignorance it will much easier. But it isn’t impossible now.

See also: How to map your custom objects in Entity Framework

Published on Databazovy Svet

How to map your custom objects in Entity Framework

Well, generating EDMX file from database and letting Visual Studio to generate all the objects is easy. But sometimes you have your custom objects with custom logic. How to solve this? In version 1 of Entity Framework this isn’t easy. It’s possible, but not easy. The good news is, that for version 2 there is huge amount of work on POCO (Plain Old CLR Objects) with persistence ignorance.

With current version you have, in general, two possible choices. The “easier” way is to derive from special object EntityObject. Anyway, this is probably what you don’t want, because you’re probably deriving from your own objects (and as we know multiple inheritance isn’t possible in C#). The other way is to implement some interfaces. It’s not so straightforward, but, at least in my opinion, more practical.

In our simple example we’ll be neither using complex types (it’s not so hard to add it) nor any associations (I’ll cover this later in other article). Let’s start with our class, I’ll call it Product and it’ll be very simple.

public class Product
{
  private int _id;
  private string _name;
  private int _price;
  
  public int ID
  {
    get { return _id; }
    set { _id = value; }
  }
  
  public string Name
  {
    get { return _name; }
    set { _name = value; }
  }
  
  public int Price
  {
    get { return _price; }
    set { _price = value; }
  }
}

As you can see, the class is really simple. You can imagine some logic i.e. on price or on name length. To make this object “tasty” for Entity Framework infrastructure you have to implement only one interface. It’s called IEntityWithChangeTracker. For associations support you should implement also IEntityWithRelationships. There’s also IEntityWithKey interface that forces you to implement EntityKey to improve performance and decrease memory usage. It’s just cherry on a pie.

The first noted interface implementation is pretty easy. You’ll just implement one method in easy way.

void IEntityWithChangeTracker.SetChangeTracker(IEntityChangeTracker changeTracker)
{
  _changeTracker = changeTracker;
}

With complex types you have also set change tracker for these using SetComplexChangeTracker method.

To make change tracker working, we need to slightly change our setters. The setters should look like this for Name property.

set
{
  if (_changeTracker != null)
    _changeTracker.EntityMemberChanging("Name");
  
  _name = value;
  
  if (_changeTracker != null)
    _changeTracker.EntityMemberChanged("Name");
}

Pretty simple, isn’t it? The last thing you have to change in your class is to add EdmScalarProperty attribute to ID, Name and Price members. That’s all you have to do with the class.

Now comes the tricky part (don’t be scared it’s not heavy magic :-) ). First you need to get SSDL, MSL and CSDL files. These files contain store-schema, mapping and conceptual-schema definition. Although you can write these files by hand, using some tool is much faster. The easiest way is to generate these using EdmGen (or maybe EdmGen2). EdmGen is standard part of Entity Framework. Just use FullGeneration mode and provide /connectionstring and /project parameters. This gives you five files in result. Delete the two with *.cs extension, you don’t need it. With EdmGen you get complete mapping for whole database so you have to delete some unnecessary stuff. Leave there only lines related to Products table (or whatever your table named is). If you don’t understand content of these files, the best way is to generate *.edmx file in Visual Studio only for our table and look at the result (EDMX file is in fact just CSDL, MSL and SSDL together plus some other stuff. You can use i.e. EdmGen2 to extract these files. But EdmGen2 isn’t standard part of Entity Framework.) right-clicking on the file and choosing Open With... and XML Editor. After this tricky part add these files to your project. On CSDL file open Properties and use for Custom Tool EntityModelCodeGenerator. This generates you new file under CSDL file. Copy content into new file and remove the Custom Tool definition. This new file contains implementation of ObjectContext class and also Products class. You can delete Products class (or class for your table), because we have ours. The last step is to replace occurrences of Products that has been removed, by Product, which is our class (you can use Products (plural), where it makes sense, of course). So the result can look like this.

public global::System.Data.Objects.ObjectQuery<Product> Products
{
  get
  {
    if ((this._Products == null))
    {
      this._Products = base.CreateQuery<Product>("[Product]");
    }
    return this._Products;
  }
}

private global::System.Data.Objects.ObjectQuery<Product> _Products;

public void AddToProducts(Product product)
{
  base.AddObject("Product", product);
}

You can also change the first constructor, if you’re interested.

After this you can use standard ways to query or update the Products table. You have to provide “entity frameworkish” connection string to make it work. The first option is to embed CSDL, MSL and SSDL files into resources and use res://<assemblyFullName>/<resourceName> specification in connection string (more info on http://msdn.microsoft.com/en-us/library/cc716756.aspx) or simply copy these three files into some folder and use path. My choice was the second (copying files into same folder as executable), so my code looks like (using MS SQL Express):

CustomClasses_EDMContext ctx = new CustomClasses_EDMContext("metadata=CustomClasses_EDM.csdl|CustomClasses_EDM.ssdl|CustomClasses_EDM.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.\sqlexpress;Initial Catalog=test;Integrated Security=True"");

var q = from p in ctx.Products
where p.ID < 200
select p;

foreach (Product p in q)
{
  Console.WriteLine(p.Name);
  p.Name = p.Name + "R";
}

ctx.AddToProducts(new Product() { Name = "New Product", Price = 999 });

ctx.SaveChanges();

When you try to run this example, you’ll be able not even to enumerate items in table (products), but also to update, add etc. it.

It’s not as fast as using designer, you have to do some manual work (but I think you can write some tool to automate it and also EdmGen2 will help), however you’re using your custom objects (without rewriting these completely).

The work on POCO and persistence ignorance in version 2 of Entity Framework will be a step forward, no doubts, but this isn’t too bad isn’t it? :-)

See also: How to use custom objects with associations in Entity Framework

Published on Databazovy Svet

Firebird (server) is back in business with Entity Framework

As you (maybe) know, there was a bug in left outer join so the model generation/update etc. in Entity Framework and similar tools was failing. The bug is now gone. Well, it’s not in some oficial release, but it’s in sources. If you want to test it, grab sources and build or grab this build (only SuperServer executable). Also take into accout, that it’s build from current sources and can be very unstable.