Entity-Framework dynamic QueryInterceptor - c#

we use entity-framework version 6.0.1 together with wcf data services. Now we build a dynamic DBContext based on this project: http://dynamixdata.codeplex.com/. This project builds dynamic poco classes with typebuilder and uses it. For server side filtering data we need a queryinterceptor. Here is an example implementation we added:
[QueryInterceptor("Interventions")]
public Expression<Func<Intervention, bool>> OnQueryInterventions()
{
var inter = ((IObjectContextAdapter)CurrentDataSource).ObjectContext.CreateObjectSet<Intervention>();
return (i => inter.Any(j => j.Object.StartsWith("changement") && i.Id == j.Id));
}
Our problem is, that we have typed classes only at runtime. So service fails because data services are checking type of object for example Intervention. Not only type there is a check to method signature. We tried to use poco-base or dynamic instead of Interventation, but that will not work, too.
Is there any other method to create Interceptors? With EF? Maybe on config creation when setting dbcontext? Any hack?
(At this moment we use server transfer to rewrite url but this is really ugly)
Thanks

Related

ASP.Net Idenity - Override FindByName to include extra search criteria

We have a setup where clients run stand-alone version of our system, but they all link to the same Identity Database with Entity Framework.
A user can be registered as a user on many versions of the application, thereby having multiple accounts with the same username, but the applicationId (stored in the web.config) is unique.
What I would like to do is use the UserManager.FindByName function, but have it automatically add the "&& applicationId = X" to the request sent to the context.
Well you can inherit from the UserManager class, but you have to rewrite the original code (.NET now is open source you can find the original code) and add your logic to it. However, this may be a lengthy action.
What i suggest is if you are using Entity Framework search for the user id by name and application id, then pass the id for the FindById method.
If follow down the implementation, you'll eventually find this method:
public virtual Task<TUser> FindByIdAsync(TKey userId)
{
this.ThrowIfDisposed();
return this.GetUserAggregateAsync((Expression<Func<TUser, bool>>) (u => u.Id.Equals(userId)));
}
In order to override this properly, it would have to be inside the UserStore class, since there are loads of internal methods (otherwise you'd have to rewrite every single internal method in the class), and add a new Type Parameter that would accept your ApplicationId, since UserStore is a generic class. Then you would be able to write another FindByIdAsync method, because it's a virtual method and it can't be overridden. You would also have to rewrite the GetUserAggregateAsync internal method, because it isn't prepared to handle your new Type Parameter.
Now, there are probably a few more hiccups that would show up, but you can, ultimately, rewrite this method to suit you, but I would advise against it because it's A LOT of work to achieve something that might be possible in another way.
Docs: http://docs.asp.net/projects/api/en/latest/autoapi/Microsoft/AspNet/Identity/EntityFramework/UserStore-TUser-TRole-TContext-TKey/index.html
Code: https://github.com/aspnet/identity/blob/master/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs

How To Serve Dynamic Objects From Odata In MVC

I am writing a generic rest service against a json database. I would like to serve my data as IQuerable OData. Do to the nature of the data, my objects are untyped dynamic objects. For instance :
[EnableQuery]
public IQueryable<dynamic> GetObjects()
{
return db.BigListOfJsonStrings
// returns dynamic object
.Select(o => System.Web.Helpers.Json.Decode(o))
.AsQueryable();
}
Now this does not work, but you get an Idea of what I am going for. The exception received is
The query specified in the URI is not valid. Could not find a property named 'propertyName' on type 'System.Object
I inspected the objects being returned, and they are in-fact type-less. They are JsonDynamicObjects a type of string dictionary (like the ExpandoObjects).
This said, what is the next step I need to take to resolve this issue ? Do I need to write a custom query provider or a custom OData provider or something ? A link to the correct documentation would be helpful.
Edit
For the time being I have this solution using dynamics on hold. I have achieved partial OData support by deserializing the objects as JObjects and manually applying the ODataQuery. It is not an ideal solution, but it works.

Returning object obtained from a WCF web service

I have a function that returns an entity obtained from a WCF web service. How should I return this entity as? I don't think I can return the original object (from the web service), because that would mean that the function's caller (from other assembly) will be forced to have a service reference to this web service (because the class is defined in the service reference) and I think I want to avoid that. And I don't think I can use interface either, since I can't modify the WCF entity to implement my interface.
On the other hand, I need to return precisely all properties that the original entity has, eg. all properties needed to be there, and there is no conversion/adjustment needed to any value or any property name and type.
Is it better to create a new class that duplicate the same properties from the original WCF class? How should I implement it, is it better to create a new object that copies all values from the original object, e.g.
return new Foo() { Id = original.Id, Name = original.Name, ... etc. }?
or just wrap it with get set methods like :
public int Id
{
get { return _original.Id; }
set { _original.Id = value; }
}
And any idea how to name the new class to avoid ambiguity with the original class name from the WCF reference?
as you have figured out, it is not a good idea to force the client to use the same types as the server. This would unnecessarily expose server application architecture to the client. The best option is to use Data Transfer Objects (DTOs).
You may have DTO for each of the entity you wish to expose to the client and the DTO will have properties to expose all the required fields of the entity. There are libraries such as value injector (valueinjecter.codeplex.com) or auto mapper as suggested by #stephenl to help you in copying the values from one object to another.
Place the DTOs in a separate namespace and assembly for best physical decoupling. You can use YourCompany.YourProduct.Data.Entities as the namespace for entities and YourCompany.YourProduct.Data.DTO for the DTOs
Actually, it depends on whether you are the consumer. If you are the consumer, reusing the type assembly is ok. However if you are not in control of the consuming services, it is better to use DTO objects with [DataContract] attributes.

How can I unit test Entity Framework Code First Mappings?

I'm using Code First to map classes to an existing database. I need a way to unit test these mappings, which are a mix of convention-based, attribute-based, and fluent-api.
To unit test, I need to confirm that properties of the classes map to the correct table and column names in the database. This test needs to be performed against the context, and should cover all configuration options for code first.
At a very high level, I'd be looking to assert something like (pseudo-code):
Assert.IsTrue(context.TableFor<Widget>().IsNamed("tbl_Widget"));
Assert.IsTrue(context.ColumnFor<Widget>(w => w.Property).IsNamed("WidgetProperty"));
Another idea to consider is using Linq and ToString().
For eaxample this :
context.Widget.Select(c => c.Property).ToString()
Will result in this for SQL Server Provider :
"SELECT [Var_3].[WidgetProperty] AS [WidgetProperty] FROM [dbo].[Widget]..."
Now we could hide it all in some Extension method that and parses resulting SQL it would look almost like Your pseudo-code :
Assert.IsTrue(context.Widgets.GetSqlColumnNameFor(w => w.Property).IsNamed("WidgetProperty"));
Draft for extension :
public string GetSqlColumnNameFor<TSource>(this DbSet<T> source, Expression<Func<TSource, TResult>> selector)
{
var sql = source.Select(selector).ToString();
var columnName = sql... // TODO : Some regex parsing
return
columnName;
}
Similary we could create GetSqlTableNameFor().
UPDATE : I decided to look for some dedicates SQL Parsers, so this solution is more generic, obviously there is such a thing for .NET :
http://www.dpriver.com/blog/list-of-demos-illustrate-how-to-use-general-sql-parser/generate-internal-query-parse-tree-in-xml-for-further-processing/
The only way I can think of to cover every possible option would be to use the Entity Framework Power Tools to pre-compile the views of your DbContext, and probably use a combination of reflection on that generated type and RegEx on the generated code itself to verify everything maps the way you want it to. Sounds pretty painful to me.
Another thing that comes to mind is creating a facade around DbModelBuilder to intercept and check everything that passes through it, but I don't know if that would handle the convention-based stuff. Also sounds painful.
As a less-complete, but much easier alternative, you can probably knock out a large portion of this by switching to attribute-based mapping wherever possible. This would allow you to create a base test class, say, ModelTesting<TEntity>, which includes a few test methods that use reflection to verify that TEntity has:
A single TableAttribute.
Each property has a single ColumnAttribute or NotMappedAttribute.
At least one property with a KeyAttribute.
Each property type maps to a compatible database type.
You could even go so far as to enforce a naming convention based on the names of the properties and class (with a caveat for table-per-hierarchy types). It would also be possible to check the foreign key mappings as well. That's a write-once base class you can derive from once for each of your model types and catch the majority of your mistakes (well, it catches the majority of mine, anyway).
Anything that can't be represented by attributes, like TPH inheritance and such, becomes a little harder. An integration test that fires up the DbContext and does a FirstOrDefault on Set<TEntity>() would probably cover most of those bases, assuming your DbContext isn't generating your database for you.
If you wrote a method
public static string ToMappingString(this Widget obj)
Then you could easily testing this via approval tests ( www.approvaltests.com or nuget)
There's a video here: http://www.youtube.com/watch?v=vKLUycNLhgc
However, if you are looking to test "My objects save and retrive themselves"
Then this is a perfect place of "Theory Based Testing"
Theory based testing
Most unit test take the form of
Given A,B expect C
Theory based testing is
Given A,B expect Theory
The beauty of this is there is no need to worry about which particular form A & B take since you don't need to know C, so any random generator will work.
Example 1: Testing Add and Subtract methods
Normally you would have stuff like
Assert.AreEqual(5, Add(2,3));
Assert.AreEqual(9, Add(10,-1));
Assert.AreEqual(10, Add(5,5));
Assert.AreEqual(7, Subtract(10,3));
However if you wrote a Theory Test it would look like
for(int i = 1; i < 100; i++)
{
int a = random.Next();
int b = random.Next();
Assert.AreEqual(a, Subtract(Add(a,b),b, string.Format("Failed for [a,b] = [{0},{1}], a,b));
}
Now that you understand Theory based testing, the theory you are trying to test is
Given Model A
When A is stored to the database, and retrieved the resulting object is equal to A

"Selecting" or "Wrapping" an IQueryable so that it is still queryable

I have a Class / API that uses an IQueryable<FirstClass> data source however I wish to expose an IQueryable<SecondClass>, where SecondClass is a wrapper class for FirstClass that exposes nearly identical properties, however for various reasons needs to inherit from an unrelated base class. For example:
// My API
void IQueryable<SecondClass> GetCurrentRecords()
{
return from row in dataSource
/* Linq query */
select new SecondClass(row);
}
// User of my API
var results = GetCurrentRecords().Where(row => row.Owner = "Mike");
Now I can make the above compile simply by using AsQueryable however I want to expose a "true" IQueryable that efficiently queries the database based on the API users query.
I know that this isn't trivial (my wrapper IQueryable implementation needs to understand the relationship between the properties of SecondClass and FirstClass), and that it has nothing to do with the Select function, but it seems like it should be possible.
How do I do this?
Note: I know that instead my API could just expose FirstClass along with a helper method to convert FirstClass to SecondClass for when the API user is "done" creating their query, but it feels messy and I don't like the idea of exposing my generated classes in this way. Also I'd like to know how to do the above anyway just from a purely academic standpoint.
Probably, you should return not an IQueriable, but Expression. Then you will be able to modify expression and let LINQ generate a query from a final Expression object. Example is here: http://msdn.microsoft.com/en-us/library/bb882637.aspx

Categories