【问题标题】:N-Tier Entity Framework fails with join queryN 层实体框架因连接查询而失败
【发布时间】:2014-04-16 08:28:58
【问题描述】:

我正在开发基于此框架的 VS2010 解决方案:http://ntieref.codeplex.com/
一切正常,我可以查询我的数据库(MS SQLServer 2008)并保存更改。

现在我正在尝试查询一个表(项目),将其与另一个表(项目-用户关联)连接起来,并通过键(用户键)进行过滤,如下所示:

var query = from p in ctx.C__E_PROJECTS.AsQueryable()
            join pu in ctx.CUMR_USER_PROJECTS_ASSOCIATION.AsQueryable() on p.CD_PROJECT equals pu.RF_PROJECT
            where pu.RF_USER == 1
            select p;

但我得到一个 [System.NotImplementedException] = {"方法或操作未实现。"} at NTier.Client.Domain\QueryProvider.cs:第 382 行(它是 N 层实体框架库的一部分)。

像这样替换连接也会产生相同的异常:

var query2 = from p in ctx.C__E_PROJECTS.AsQueryable()
             from pu in ctx.CUMR_USER_PROJECTS_ASSOCIATION.AsQueryable()
             where p.CD_PROJECT == pu.RF_PROJECT
                && pu.RF_USER == 1
             select p;

我做错了吗?
还有其他方法可以让一个表在与另一个表的连接中过滤吗?

这是两个表的定义: (其中 Entity 是 NTier.Common.Domain.Model.Entity)

[DataContract(IsReference = true)]
[KnownType(typeof(C__E_PROJECT_VERSIONS))]
[KnownType(typeof(CUMR_USER_PROJECTS_ASSOCIATION))]
[MetadataType(typeof(C__E_PROJECTSMetadata))]
public class C__E_PROJECTS : Entity<C__E_PROJECTS>, INotifyPropertyChanged, INotifyPropertyChanging, IDataErrorInfo
{
    public C__E_PROJECTS();

    [DataMember]
    [NavigationProperty]
    public TrackableCollection<C__E_PROJECT_VERSIONS> C__E_PROJECT_VERSIONS { get; set; }
    [DataMember]
    [Required]
    [SimpleProperty]
    [ServerGeneration(1)]
    [Key]
    public int CD_PROJECT { get; set; }
    [NavigationProperty]
    [DataMember]
    public TrackableCollection<CUMR_USER_PROJECTS_ASSOCIATION> CUMR_USER_PROJECTS_ASSOCIATION { get; set; }
    [DataMember]
    [SimpleProperty]
    public string DS_PROJECT { get; set; }
    [SimpleProperty]
    [DataMember]
    [Required]
    public string ID_PROJECT { get; set; }

    protected override void ClearNavigationProperties();
    protected override int GetKeyHashCode();
    protected override bool IsKeyEqual(C__E_PROJECTS entity);
}

[DataContract(IsReference = true)]
    [KnownType(typeof(CUME_USERS))]
    [MetadataType(typeof(CUMR_USER_PROJECTS_ASSOCIATIONMetadata))]
    [KnownType(typeof(C__E_PROJECTS))]
    public class CUMR_USER_PROJECTS_ASSOCIATION : Entity<CUMR_USER_PROJECTS_ASSOCIATION>, INotifyPropertyChanged, INotifyPropertyChanging, IDataErrorInfo
    {
        public CUMR_USER_PROJECTS_ASSOCIATION();

        [NavigationProperty]
        [DataMember]
        public C__E_PROJECTS C__E_PROJECTS { get; set; }
        [DataMember]
        [SimpleProperty]
        public bool? CAN_READ { get; set; }
        [DataMember]
        [NavigationProperty]
        public CUME_USERS CUME_USERS { get; set; }
        [DataMember]
        [Key]
        [Required]
        [SimpleProperty]
        public int RF_PROJECT { get; set; }
        [SimpleProperty]
        [Key]
        [DataMember]
        [Required]
        public int RF_USER { get; set; }

        protected override void ClearNavigationProperties();
        protected override int GetKeyHashCode();
        protected override bool IsKeyEqual(CUMR_USER_PROJECTS_ASSOCIATION entity);
    }


作为一种解决方法,我在返回查询结果的 SQL Server 存储过程中实现了连接查询,并将存储过程添加到 edmx 模型中。一切正常。
现在保存 edmx 或运行“N-Tier Entity Generator”自定义工具,我希望在客户端的上下文中具有相关功能,但它丢失了。我可以在 XXX.Server.Domain.Repositories 项目中看到它,但它没有传播到客户端。我必须编辑 T4 模板吗?

谢谢!
罗伯托

【问题讨论】:

标签: c# entity-framework n-tier-architecture


【解决方案1】:

关于你的更新,试试这个:

var query = from p in ctx.PROJECTS.AsQueryable().Include("USER_PROJECTS_ASSOCIATION")
            from q in p.USER_PROJECTS_ASSOCIATION.AsQueryable()
            where q.USER_PROJECTS_ASSOCIATION.RF_USER==1
            select p; // or try Select q;

希望对你有帮助。

【讨论】:

  • 它给出了同样的例外。我下载了 N 层实体框架库的源代码并尝试对其进行调试:当在查询中使用“join”或多个“from”时,它以抛出 NotImplemented 异常的方法结束。我会尝试弄清楚是否可以实现该方法。
  • 当你只处理一个实体时?
  • 此外,在查询更新后的答案时,它会给出 NotImplemented 异常。只有一个实体它才能正常工作。您评论中的查询工作正常(使用 ctx 而不是 p)。
  • 如果您有此查询的结果。由于缺少 ctx,我将其删除。然后你能做第一个查询比较第二个查询的结果吗?RF_USER==1
  • 是的,谢谢,考虑到(项目表的,未过滤的)数据量有限,这可以作为此查询的解决方案,但这只是一个简单的案例。我将需要在我的应用程序的其他部分进行更复杂的查询。我想了解的是,N-Tier Entity Framework 是否适合我的目的。我可以说这是一个非常好的库,我要感谢开发人员 (@ChristofSenn) 所做的工作。但在这一刻,我不确定它是否能满足我的要求。我希望克里斯托夫会看看这个问题。
【解决方案2】:

一般...

N-Tier Entity Framework 生成客户端和服务器代码来查询支持排序(orderby 等)、过滤(where)、分页(skip and take)和包括关系(include)的实体。此操作是端到端的,即客户端定义 linq 查询,通过 WCF 传输到服务器并最终在数据库上执行。可以在服务器 (DataService) 或客户端数据上下文 (DataContext) 上手动添加更复杂的查询操作,如投影、聚合和连接。所有相关的接口和类都是部分生成的,我很容易使用部分接口和类进行扩展:

在服务器上

-   partial interface IMyDataService
-   partial class MyDataService

在客户端

-   partial interface IMyDataContext
-   partial class MyDataContext

此外,存储过程不会由框架生成的代码自动公开。如果您愿意,可以修改代码生成(T4 文件)或将自定义方法添加到数据服务和客户端数据上下文。

你的情况……

根据您的意图,您可以执行以下操作:

var query = 
  from p in ctx.PROJECTS.AsQueryable()
                        .Include(“USER_PROJECTS_NAVIGATION_PROPERTY”)
  where p.USER_PROJECTS_NAVIGATION_PROPERTY.RF_USER == 1
  select p;

或者,如果您需要更复杂的东西,可以使用上面列出的部分类将其实现为自定义方法。

【讨论】:

  • 感谢您为我指明了正确的方向。我已经扩展了部分类(在服务器端和客户端),我可以从数据库中获取所需的数据。
  • 我有一个问题:我在客户端的 QueryResult 中有数据;我怎样才能让我合并到上下文的表中?我尝试在循环中调用 Attach,就像 var result = ctx.GetProjectsByUser(new ClientInfo(), 1); foreach(var project in result.Data) { ctx.C__E_PROJECTS.Attach(project); } 一样,但是在附加第一个项目之后,我得到的表中填充了数据库中的所有项目。我做错了吗?
  • 将实体附加到客户端数据上下文会自动将所有相关实体(即可通过导航属性访问的父实体和子实体)附加到客户端数据上下文。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多