The way to do this:
1: using (var dc = new xxxxEntities())
2: {
3: ((IObjectContextAdapter)dc).ObjectContext.Connection.Open();
4: dc.Database.ExecuteSqlCommand(@"USE FEDERATION FederationName (FederationKeyName = FederationKey) WITH FILTERING = ON, RESET");
5: using (var scope = new TransactionScope (TransactionScopeOption.RequiresNew))
6: {
7: [...]
8: }
9: }
I have implemented it in a project and it works well with Entity Framewok 5.0.0 but an exception is thrown with Entity Framework 6.0.0-alpha3: "USE FEDERATION statement not allowed within multi-statement transaction."
I have created an issue on the Entity Framework Codeplex: "EF 6 and SQL Azure Federations".
Entity Framework 6 is very important for SQL Azure because it will contain a system of connection resiliency like the Transient Fault Handling Application Block can do. I hope that a solution will be found soon!
Moreover, like in my previous article: Don't Repeat Yourself!
If you want to use Entity Framework with SQL Azure Federation, take a look at this base repository class:
1: using System;
2: using System.Data.Entity;
3: using System.Data.Entity.Infrastructure;
4: using System.Transactions;
5:
6: namespace Admin.Persistence.Repositories.Impl
7: {
8: public class FederatedRepository
9: {
10: protected string FederationName { get; set; }
11: protected string FederationKeyName { get; set; }
12:
13: public FederatedRepository(string federationName, string federationKeyName)
14: {
15: FederationName = federationName;
16: FederationKeyName = federationKeyName;
17: }
18:
19: protected TK Execute<T, TK>(Func<T, TK> f, object federationKey) where T : DbContext, new()
20: {
21: TK result;
22:
23: using (var db = new T())
24: {
25: SetFederationScope(db, federationKey);
26:
27: using (var transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))
28: {
29: result = f(db);
30: transactionScope.Complete();
31: }
32: }
33:
34: return result;
35: }
36:
37: private void SetFederationScope(DbContext dbContext, object federationKey)
38: {
39: var federationCmdText = string.Format(@"USE FEDERATION {0} ({1}={2}) WITH FILTERING=ON, RESET", FederationName, FederationKeyName, federationKey);
40: ((IObjectContextAdapter)dbContext).ObjectContext.Connection.Open();
41: dbContext.Database.ExecuteSqlCommand(federationCmdText);
42: }
43: }
44: }
The utilisation is the same than in my previous article ;-)
Just wondering why you use TransactionScope here, rather than rely on the transaction that is implicit with dc.SaveChanges?
ReplyDeleteThanks for your article, it was very helpful to me.
Hi turquoiseowl,
ReplyDeleteThank you for your comment, glad that it was useful for you!
I'm using the TransactionScope because Azure Federation and Entity Framework is a little bit tricky for the moment and I have had follow this article from Microsoft: http://msdn.microsoft.com/en-us/library/windowsazure/hh703245.aspx