LINQ to Entities through Interface Property
Asked Answered
R

3

9

I have a situation where I would like to use a single business logic class to perform similar operations on a variety of entity framework classes. I have defined an interface which these classes implement in a partial class file.

However when I try to write a LINQ to entities query against these interface methods I get a NotSupportedException since the query is not using the class's properties directly but through an interface.

I would like to keep the heavy lifting to the database tier so is there a way to achieve this without resorting to LINQ to objects?

Here is some code which demonstrates my problem (it is using a generic repository class created by a factory).

public interface INamedEntity
{
    int ID { get; set; }
    string Name { get; set; }
}

// This is an Entity Framework class which has CustomerID and CustomerName properties.
public partial class Customer: INamedEntity
{
    int INamedEntity.ID
    {
        get { return this.CustomerID; }
        set { this.CustomerID = value; }
    }
    string INamedEntity.Name
    {
        get { return this.CustomerName; }
        set { this.CustomerName = value; }
    }
}

...

public string GetName<T>(int entityID) where T: EntityObject, INamedEntity
{
    using(var repository = RepositoryFactory.CreateRepository<T>())
    {
        return repository
            .Where(e => e.ID == entityID)
            .Select(e.Name)
            .Single();
    }
}
Recommit answered 17/2, 2012 at 10:20 Comment(0)
C
6

This is not supported. Your Linq-to-entities query can use only mapped properties of your entities. If you use interface properties EF doesn't know how to convert them to SQL because it is not able to analyze your code in property implementation.

Don't use interfaces for entities - EF doesn't support it at all. In your special case it will even not work with any other ORM because you are querying on properties which are unknown to mapping. This would require you to build your own Linq provider translating your query to query with real mapped properties.

Clamatorial answered 17/2, 2012 at 10:45 Comment(6)
But is there any way to achieve this kind of pattern. Ideally there would be business logic units for each area of functionalty, working on an interface and mapping to all relevant entities.Recommit
But that means another "mapping" layer on top of EF which will translate your business logic interface properties to real EF properties. This mapping layer will also transform queries. I don't call this pattern - I call it over architected application.Clamatorial
Over-architected perhaps, but how do you avoid copying and pasting the same code into several business layer objects so that they can perform the same logic, but using differently named entity properties?Recommit
It is too abstract question to be answered - the only reaction can be: refactoring. Simply you have a EF model and you want to define L2E queries somewhere => that "somewhere" must use real EF mapped properties. All your additional property "names" are redundant.Clamatorial
I think perhaps I have failed to explain the problem domain in sufficient detail. Thank you for your replies, I will reconsider my question.Recommit
Well this is a bummer, I'm glad that I didn't spend too much time trying.Jairia
B
2

You can use Dynamic Query Library (http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx).

        if (typeof (INamedEntity).IsAssignableFrom(typeof (T)))
        {
            q = q.Where("ID ==@0", id);
        }
Brownell answered 2/8, 2013 at 12:11 Comment(0)
C
0

The following exception occures during query execution based on a generic source and with interface member used in the where clause.

NotSupportedException: The mapping of interface member [InterfaceName].[MemberName] is not supported.

The exception occures only when the query should return multiple items and when I used == operator. I could not reproduce the error when executed the query with First, FirstOrDefault or Single, or when I used equals or other operator in the where clause.

Reference : Interface not supported

Chiton answered 17/2, 2012 at 10:35 Comment(1)
Yes, that looks like the issue.Recommit

© 2022 - 2024 — McMap. All rights reserved.