我正在寻找特定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中正常完成。所有人都非常感激。
SQL查询我想用Linq构建:
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; }
}
答案 0 :(得分:1)
问题在于您的要求:
我想返回主实体的所有实例 与一个N:N关系中的给定ID相关联,并且不相关联 在其他N:N关系中使用相同的ID。
使用Dynamics CRM中的Linq查询无法实现此目的。针对Dynamics CRM的Linq查询将转换为QueryExpression
个查询。使用QueryExpression,无法选择不与其他记录关联的记录。
同样重要的是:LINQ for CRM不支持左外连接,但QueryExpression
查询支持左外连接。
您唯一的选择是选择(希望)更多的记录,然后过滤掉之后不需要的记录。
答案 1 :(得分:1)
一句警告:当我不得不面对类似的要求时,以下内容对我有用,但根据数据,其他自定义等,它可能会对系统造成性能损失。彻底的测试是必须即可。
你可以&#34;作弊&#34;通过这个插件你的方式。
您现在可以查询MainEntity
并了解您需要的所有内容,不需要更多显式连接(如果您需要/想要它,您也可以将列表作为视图)。