Created
August 14, 2014 16:10
-
-
Save jamesrcounts/1e6b3b8a8767bf1e2555 to your computer and use it in GitHub Desktop.
EF6 Adapter, works with CodeFirst. Main difference is the namespaces. Also, better error checking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ApprovalTests.Persistence.EntityFramework.Version6 | |
{ | |
using System; | |
using System.Data.Common; | |
using System.Data.Entity; | |
using System.Data.Entity.Core.EntityClient; | |
using System.Data.Entity.Core.Objects; | |
using System.Data.Entity.Infrastructure; | |
using System.Linq; | |
using System.Reflection; | |
using ApprovalUtilities.Persistence.Database; | |
public static class EntityFrameworkDbContextApprovals | |
{ | |
public static void Verify<T>(DbContext db, IQueryable<T> queryable) | |
{ | |
DatabaseApprovals.Verify(new DbContextAdaptor<T>(db, queryable)); | |
} | |
} | |
public static class EntityFrameworkUtils | |
{ | |
public static DbConnection GetConnectionFrom(ObjectContext context) | |
{ | |
return ((EntityConnection)context.Connection).StoreConnection; | |
} | |
public static string GetQueryFromQueryable(ObjectQuery value) | |
{ | |
var seed = value.ToTraceString(); | |
return value.Parameters.Aggregate(seed, (current, p) => current.Replace("@" + p.Name, "'" + p.Value + "'")); | |
} | |
} | |
public sealed class DbContextAdaptor<T> : IDatabaseToExecuteableQueryAdaptor | |
{ | |
private readonly DbContext db; | |
private readonly IQueryable<T> queryable; | |
public DbContextAdaptor(DbContext db, IQueryable<T> queryable) | |
{ | |
this.db = db; | |
this.queryable = queryable; | |
} | |
public DbConnection GetConnection() | |
{ | |
return GetConnectionFrom(this.db); | |
} | |
public string GetQuery() | |
{ | |
return EntityFrameworkUtils.GetQueryFromQueryable(GetObjectQuery((DbQuery<T>)this.queryable)); | |
} | |
private static DbConnection GetConnectionFrom(DbContext context) | |
{ | |
return context.Database.Connection; | |
} | |
private static ObjectQuery<T1> GetObjectQuery<T1>(DbQuery<T1> query) | |
{ | |
const string InternalQueryName = "_internalQuery"; | |
var internalQuery = | |
query.GetType() | |
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic) | |
.FirstOrDefault(f => f.Name.Equals(InternalQueryName)); | |
if (internalQuery == null) | |
{ | |
throw new InvalidOperationException("Could not get field information for: " + InternalQueryName); | |
} | |
var obj = internalQuery.GetValue(query); | |
const string ObjectQueryName = "_objectQuery"; | |
var objectQuery = | |
obj.GetType() | |
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic) | |
.FirstOrDefault(f => f.Name.Equals(ObjectQueryName)); | |
if (objectQuery == null) | |
{ | |
throw new InvalidOperationException("Could not get field information for: " + ObjectQueryName); | |
} | |
var value = objectQuery.GetValue(obj); | |
if (value == null) | |
{ | |
throw new InvalidOperationException(ObjectQueryName + " was null."); | |
} | |
var oq = value as ObjectQuery<T1>; | |
if (oq == null) | |
{ | |
throw new InvalidCastException("Could not convert <" + value.GetType() + "> to <" + typeof(ObjectQuery<T1>) + ">"); | |
} | |
return oq; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment