6

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

然而,当我尝试写一个LINQ到实体查询针对这些接口中的方法,因为查询不直接,但通过一个接口使用类的属性,我得到一个NotSupportedException异常。

我想繁重存到数据库层等是有办法做到这一点,而不诉诸LINQ的对象?

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

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

回答

0

查询执行期间发生以下异常,该异常基于泛型源和where子句中使用的接口成员。

NotSupportedException异常:接口构件[InterfaceName中] [成员名称]的映射不被支持。

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

参考:Interface not supported

+0

是的,这看起来像问题。 – gareththegeek 2012-02-17 10:50:41

5

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

不要为实体使用接口 - EF根本不支持它。在你的特殊情况下,它甚至不能与任何其他ORM一起工作,因为你正在查询映射未知的属性。这需要您构建自己的Linq提供程序,将您的查询翻译为使用真实映射属性进行查询。

+0

但是有什么办法可以实现这种模式。理想情况下,每个功能区域都会有业务逻辑单元,在接口上工作并映射到所有相关实体。 – gareththegeek 2012-02-17 10:53:00

+1

但是这意味着EF上的另一个“映射”层将会将您的业务逻辑接口属性转换为真正的EF属性。该映射层也将转换查询。我不称这种模式 - 我称它为架构应用程序。 – 2012-02-17 11:23:01

+0

也许是超架构,但是如何避免将相同的代码复制并粘贴到多个业务层对象中,以便它们可以执行相同的逻辑,但是使用不同名称的实体属性? – gareththegeek 2012-02-17 13:46:07