[英]Linq join to perform specific query against Dynamics CRM 2015
我正在寻找有关特定Linq连接查询的帮助。 我的Linq知识非常基础,我整天都在努力编写正确的联接代码。
我实际上是在尝试使用由CrmSvcUtil.exe实用工具生成的ServiceContext,来与Dynamics CRM Online 2015 SDK一起使用的Linq查询。
显然,CRM Linq提供程序存在局限性( ref1 , ref2 , ref3等)。 在使用我熟悉的Linq查询时,经常会出现以下错误。 似乎答案是使用更自然的Linq连接。
Invalid 'where' condition. An entity member is invoking an invalid property or method.
与其向您展示我的100多次失败尝试,不如说我想使用SQL示例来演示我要实现的目标更好。 下面的示例脚本。 本质上,我有一个实体,要为之返回记录列表。 与另一个实体有两个N:N关系。 我想返回主实体的所有实例,在该实例中,它与一个N:N关系中的给定ID关联,而不与另一N:N关系中的相同ID关联。
我最努力的部分是执行同时包含内部联接和左侧外部联接的Linq查询。 即使您没有使用CRM Linq Provider的直接经验,它可能仍然对我有帮助,只是看看如何在Linq中正常进行。 所有帮助,不胜感激。
我要使用Linq构建的SQL查询:
DECLARE @id INT = 1
-- Should only return entities with IDs 1 and 2
SELECT a.* FROM [dbo].[MainEntity] a
INNER JOIN [dbo].[AltOne] b ON a.EntityID = b.EntityID AND b.AltOneID = @id
LEFT JOIN [dbo].[AltTwo] c ON a.EntityID = c.EntityID AND c.AltOneID = @id
WHERE c.AltOneID IS NULL
数据库设置脚本:
CREATE TABLE [dbo].[MainEntity](
[EntityID] [int] NOT NULL,
[EntityName] [varchar](50) NOT NULL,
CONSTRAINT [PK_MainEntity] PRIMARY KEY CLUSTERED
(
[EntityID] ASC
)
)
GO
CREATE TABLE [dbo].[AltOne](
[EntityID] [int] NOT NULL,
[AltOneID] [int] NOT NULL,
CONSTRAINT [PK_AltOne] PRIMARY KEY CLUSTERED
(
[EntityID] ASC,
[AltOneID] ASC
)
)
GO
ALTER TABLE [dbo].[AltOne] WITH CHECK ADD CONSTRAINT [FK_AltOne_MainEntity] FOREIGN KEY([EntityID])
REFERENCES [dbo].[MainEntity] ([EntityID])
GO
ALTER TABLE [dbo].[AltOne] CHECK CONSTRAINT [FK_AltOne_MainEntity]
GO
CREATE TABLE [dbo].[AltTwo](
[EntityID] [int] NOT NULL,
[AltOneID] [int] NOT NULL,
CONSTRAINT [PK_AltTwo] PRIMARY KEY CLUSTERED
(
[EntityID] ASC,
[AltOneID] ASC
)
)
GO
ALTER TABLE [dbo].[AltTwo] WITH CHECK ADD CONSTRAINT [FK_AltTwo_MainEntity] FOREIGN KEY([EntityID])
REFERENCES [dbo].[MainEntity] ([EntityID])
GO
ALTER TABLE [dbo].[AltTwo] CHECK CONSTRAINT [FK_AltTwo_MainEntity]
GO
INSERT INTO [dbo].[MainEntity] ([EntityID], [EntityName]) VALUES (1, 'Test 1')
INSERT INTO [dbo].[MainEntity] ([EntityID], [EntityName]) VALUES (2, 'Test 2')
INSERT INTO [dbo].[MainEntity] ([EntityID], [EntityName]) VALUES (3, 'Test 3')
GO
INSERT INTO [dbo].[AltOne] ([EntityID], [AltOneID]) VALUES (1, 1)
INSERT INTO [dbo].[AltOne] ([EntityID], [AltOneID]) VALUES (1, 2)
INSERT INTO [dbo].[AltOne] ([EntityID], [AltOneID]) VALUES (2, 1)
INSERT INTO [dbo].[AltOne] ([EntityID], [AltOneID]) VALUES (2, 2)
INSERT INTO [dbo].[AltOne] ([EntityID], [AltOneID]) VALUES (3, 1)
GO
INSERT INTO [dbo].[AltTwo] ([EntityID], [AltOneID]) VALUES (3, 1)
INSERT INTO [dbo].[AltTwo] ([EntityID], [AltOneID]) VALUES (1, 2)
INSERT INTO [dbo].[AltTwo] ([EntityID], [AltOneID]) VALUES (2, 2)
GO
编辑1:
根据要求添加示例类。 重申一下,我需要返回MainEntity
对象的集合, 而不必直接使用其ICollection
属性,而应使用联接(这似乎是CRM Linq Provider的限制)。 该列表必须是不相关的特定对象RelatedEntity
通过CollectionOne
, 但与同一RelatedEntity
通过CollectionTwo
。 我希望这很清楚。
public class MainEntity
{
public int EntityID { get; set; }
public string EntityName { get; set; }
public ICollection<RelationshipOne> CollectionOne { get; set; }
public ICollection<RelationshipTwo> CollectionTwo { get; set; }
}
public class RelationshipOne
{
public int EntityID { get; set; }
public int AltOneID { get; set; }
public ICollection<MainEntity> MainEntities { get; set; }
public ICollection<RelatedEntity> RelatedEntities { get; set; }
}
public class RelationshipTwo
{
public int EntityID { get; set; }
public int AltOneID { get; set; }
public ICollection<MainEntity> MainEntities { get; set; }
public ICollection<RelatedEntity> RelatedEntities { get; set; }
}
public class RelatedEntity
{
public int RelatedEntityID { get; set; }
public string RelatedEntityName { get; set; }
public ICollection<RelationshipOne> RelationshipOnes { get; set; }
public ICollection<RelationshipTwo> RelationshipTwos { get; set; }
}
public class DummyContext
{
public System.Data.Entity.DbSet<MainEntity> MainEntitySet { get; set; }
public System.Data.Entity.DbSet<RelationshipOne> RelationshipOneSet { get; set; }
public System.Data.Entity.DbSet<RelationshipTwo> RelationshipTwoSet { get; set; }
public System.Data.Entity.DbSet<RelatedEntity> RelatedEntitySet { get; set; }
}
问题出在您的要求上:
我想返回主实体的所有实例,在该实例中,它与一个N:N关系中的给定ID关联,而不与另一N:N关系中的相同ID关联。
您无法在Dynamics CRM中使用Linq查询来完成此任务。 Dynamics CRM的Linq查询将转换为QueryExpression
查询。 使用QueryExpression不可能选择未与其他记录关联的记录。
还要提及的重要一点:LINQ for CRM不支持左外部联接,但QueryExpression
查询支持。
您唯一的选择是(希望)多选择一些记录并过滤之后不需要的记录。
提醒一下:当我不得不面对类似的要求时,以下内容对我有用,但这取决于数据,其他自定义设置等,可能会对系统造成性能影响。 必须进行全面测试。
您可以使用插件“欺骗”您的方法。
现在,您可以查询MainEntity
并知道所需的一切,不需要更多的显式联接(如果需要/也可以将列表作为View使用)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.