Using EF Core 2.1.2. For the simplest possible example, let's say I have a class called Foo
:
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("EntityId")]
public virtual ICollection<FooPropertyValue> PropertyValues { get; set; }
}
a class called FooPropertyValue
:
public class FooPropertyValue
{
public int PropertyId { get; set; }
[ForeignKey("PropertyId")]
public virtual FooProperty Property { get; set; }
public int EntityId { get; set; }
public string Value { get; set; }
}
and a class called FooProperty
:
public class FooProperty
{
public int Id { get; set; }
public string Name { get; set; }
public string CSharpType { get; set; } // System.Date, System.String, System.Int32 etc.
}
So it's a simple EAV model.
Now is it possible to utilize that CSharpType
property when querying this model?
Let's consider this query as an example:
// Let's assume:
// the 'table' variable is IQueryable<Foo>
// the 'propertyId' is passed as a parameter
// the 'value' is passed as a parameter, and is of type System.String
// the 'CSharpType' for this property is 'System.DateTime'
// the requested property value exists, i.e. 'FirstOrDefault' will not return null
var result = table.Where(x => x.PropertyValues.FirstOrDefault(p => p.PropertyId == propertyId)).Value == value)
This query will go though, but it will return something only if the stored value is identical to the passed value and as a plus, it will be slow.
Is it possible to convert the value
to DateTime
before passing it to the query method, build the Where
expression dynamically to treat the Value
property of FooPropertyValue
as DateTime
(although I don't know how to do this step, I think Reflection will not allow to call Expression.Equal
where the left-side Expression.Property
has string
type and right-side Expression.Constant
has DateTime
type), pass that built expression to ´Where´ and expect the call to go through?
I ask because, when you store dynamic values in a nvarchar
column in SQL Server, it's possible (when the type is known at runtime) to use CAST(Value as {VALUETYPE})
in ´WHERE´ clause and make the query somewhat faster (but also more usable when dealing with dates, for example). Is this possible using EF Core?
EDIT: Actually the query can't be any faster when using CAST, but still the question remains, as it'd be a pain in the ass to query some data types such as decimal
, DateTime
etc. using string
values.