通过接口属性的 LINQ to Entities

发布于 2025-01-06 17:29:41 字数 1056 浏览 1 评论 0 原文

我有一种情况,我想使用单个业务逻辑类对各种实体框架类执行类似的操作。我已经定义了这些类在部分类文件中实现的接口。

但是,当我尝试针对这些接口方法编写 LINQ to 实体查询时,我收到 NotSupportedException,因为查询不是直接使用类的属性,而是通过接口使用。

我想将繁重的工作保留在数据库层,那么有没有一种方法可以在不诉诸 LINQ to object 的情况下实现这一目标?

这是一些代码,它演示了我的问题(它使用由工厂创建的通用存储库类)。

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();
    }
}

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();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

也只是曾经 2025-01-13 17:29:41

不支持此操作。您的 Linq-to-entities 查询只能使用实体的映射属性。如果您使用接口属性,EF 不知道如何将它们转换为 SQL,因为它无法分析属性实现中的代码。

不要对实体使用接口 - EF 根本不支持它。在您的特殊情况下,它甚至无法与任何其他 ORM 一起使用,因为您正在查询映射未知的属性。这需要您构建自己的 Linq 提供程序,将查询转换为具有实际映射属性的查询。

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.

神回复 2025-01-13 17:29:41

您可以使用动态查询库(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);
        }

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);
        }
又怨 2025-01-13 17:29:41

在基于通用源并在 where 子句中使用接口成员的查询执行期间,会发生以下异常。

NotSupportedException:不支持接口成员 [InterfaceName].[MemberName] 的映射。

仅当查询应返回多个项目并且我使用 == 运算符时,才会发生异常。当使用 First、FirstOrDefault 或 Single 执行查询时,或者在 where 子句中使用 equals 或其他运算符时,我无法重现该错误。

参考: 接口不支持

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文