I'm using PostSharp aspects to "inject" properties into some classes, and those classes will be stored (code first) in a DB by Entity Framework. Later on, I'd like to query and access the injected properties of each class in queries. For example, say I'm writing an aspect that injects an "id" property into objects:
interface IIdentifyable
{
string id { get; set; }
}
[IntroduceInterface(typeof(IIdentifyable))]
[Serializable]
public class IdentifiableAspect : InstanceLevelAspect, IIdentifyable
{
[Key]
[IntroduceMember]
public virtual string id { get; set; }
public override void RuntimeInitializeInstance()
{
id = Guid.NewGuid().ToString();
base.RuntimeInitializeInstance();
}
}
[Serializable]
[IdentifiableAspect]
public class Car
{
// ...
}
Now I want to use the "injected" id property of the Car class in entity framework linq queries. Say for example I'd like to count all cars whose id contains the number 1. I've tried several methods, none of which works:
// Throws exception
// LINQ to Entities does not recognize the method IIdentifyable Cast[Car,IIdentifyable](car) method, and this method cannot be translated into a store expression.
dbContext.cars.Where(car => Post.Cast<Car, IIdentifyable>(car).id.Contains("1")).Count();
// Throws exception
// IIdentifyable is not a valid metadata type for type filtering operations. Type filtering is only valid on entity types and complex types.
dbContext.cars.OfType<IIdentifyable>().Where(car => car.id.Contains("1")).Count();
// Throws exception
// Unable to cast the type Car to type IIdentifyable. LINQ to Entities only supports casting EDM primitives or enumeration types.
dbContext.cars.Where(car => ((IIdentifyable)car).id.Contains("1")).Count();
Is there any way to do this, or no way at all to use PostSharp in conjunction with EF that particular way?
Thanks.
I'm not sure of your project setup, but I'll make the assumption everything is in the same project:
You'll need to define your classes in a seperate assembly. I don't think you can use injected properties in the same project where you apply the aspect because I beleieve PostSharp happens post compiliation. You'll need to do your Linq stuff in a new project that will reference the compiled output.
E.x.: ProjectA <-- define your aspects here ProjectB <-- define your classes here. Make it reference ProjectA ProjectC <-- Define your linq queries here
Your other alternative is to use the dynamic keyword and lose your compile type checking.