【问题标题】:LINQ to entity, wrong join typeLINQ to entity,错误的连接类型
【发布时间】:2013-03-22 00:24:41
【问题描述】:

我有一个看起来像这样的查询......

var q = Dal.TBLINVENTORies.Where(i => i.SHOWIT);
q = q.Where(i => i.dtStart < DateTime.Now || i.dtStart == null);
q = q.Where(i => i.dtEnd > DateTime.Now || i.dtEnd == null);
q = q.Where(i => i.sSystem.Contains("OE"));
q = q.Where(i => i.WS_ActiveList_ID == 0 || i.tblWS_ActiveList.WS_MasterList_ID == 16);
var test2 = q.ToList();

在“ToList()”之前,如果我检查查询,我会得到以下 sql(或多或少)

SELECT [Extent1].*
FROM  [dbo].[TBLINVENTORY] AS [Extent1]
INNER JOIN [dbo].[tblWS_ActiveList] AS [Extent2] ON [Extent1].[WS_ActiveList_ID] = [Extent2].[ID]
WHERE ([Extent1].[SHOWIT] = 1) 
AND (([Extent1].[dtStart] <  CAST( SysDateTime() AS datetime2)) OR ([Extent1].[dtStart] IS NULL)) 
AND (([Extent1].[dtEnd] >  CAST( SysDateTime() AS datetime2)) OR ([Extent1].[dtEnd] IS NULL)) 
AND ([Extent1].[sSystem] LIKE '%OE%') 
AND ([Extent1].[WS_ActiveList_ID] = 0  OR [Extent2].[WS_MasterList_ID] = 16)

不幸的是,这不是我需要的,因为“Inventory”和“ActiveList”之间的关系并不是真正的一对多,而是零对多(我不确定我是否使用了正确的术语)。基本上,一个库存项目可能有也可能没有相关的“ActiveList”。

如果我将原始 SQL 更改为使用 LEFT OUTER JOIN,而不是 INNER JOIN,SQL 将返回我期望的值。

强制 LEFT OUTER JOIN 需要什么?

我已经尝试过 Linq to entities - One to many relationship - need left outer join instead of cross join 推荐的解决方案,但是,

var q2 = from inv in Dal.TBLINVENTORies from al in inv.tblWS_ActiveList

返回错误:

Error 65 An expression of type 'xxxx.DAL.tblWS_ActiveList' is not allowed in a subsequent from clause in a query expression with source type 'System.Data.Entity.DbSet&lt;xxxx.DAL.TBLINVENTORY&gt;'. Type inference failed in the call to 'SelectMany'.

我想知道我的链接/关系是否构造不正确?还有其他想法吗?

谢谢!

编辑 :: 附加数据

-- create foreign key, but don't enforce on existing values
ALTER TABLE [dbo].[tblInventory]  --the ONE Table
    WITH NOCHECK 
    ADD CONSTRAINT [FK__tblInventory.WS_ActiveList_ID__tblWS_ActiveList.ID] 
        FOREIGN KEY([WS_ActiveList_ID]) 
            REFERENCES [dbo].[tblWS_ActiveList] ([ID])    --the MANY Table
        NOT FOR REPLICATION
GO

-- disable enforcement of the foreign key, but leave it in place (virtual key)
ALTER TABLE [dbo].[tblInventory]  
    NOCHECK CONSTRAINT [FK__tblInventory.WS_ActiveList_ID__tblWS_ActiveList.ID] 
GO

以及WS_ActiveList_ID的定义:

[WS_ActiveList_ID] [int] NOT NULL CONSTRAINT [DF_TBLINVENTORY_WS_ActiveList_ID] DEFAULT (0),

【问题讨论】:

  • 您能说明与 WS_ActiveList 的关系是如何配置的吗?它是一个可以为空的关系还是你使用 0 来表示一个空关系?
  • 0 来表示。你要我挖掘和展示什么数据?我将获取关系的 SQL 定义....如果您需要其他内容,请告诉我。
  • 尝试将 FK 属性更改为 Nullable
  • 我对进行该更改有一些遗留问题(我假设您是说不要在 SQL 定义中设置 tblInventory.WS_ActiveList_IDNOT NULL
  • EF 假定 0 或 1 到多个使用 null 来表示 0。我知道没有办法在 EF 中进行连接工作,您的值为 0 表示没有连接。尽管您可能会制定联接以排除 0

标签: asp.net-mvc linq entity-framework


【解决方案1】:

您的主要问题是您关闭了数据库中的参照完整性检查。

除了坏数据的明显问题外,这不适用于 EF。

到目前为止,最好的选择是使WS_ActiveList_ID 可以为空,更新您的数据以将所有0s 更改为NULLs 并重新打开约束。

如果你不能这样做,我认为你必须生成一个 SQL 语句作为字符串并使用dbContext.Database.SqlQuery&lt;T&gt; (MSDN) 执行它

【讨论】:

  • :D 是的,我认为有人会对此发表评论。 “问题”是这是一个旧的(12 年或更早的)遗留系统,它从一开始就没有任何关键关系,更不用说 RI。
  • ....现在我正在使用带有 EF 的 asp.net mvc 重写应用程序的部分内容,我开始根据需要添加它们,但只是部分添加,因为所有已经存在的遗留数据中,否则会失败......有一天“很快”我们将开始修复数据方面,并添加 RI,但现在,这就是我们所拥有的。跨度>
  • 您能否指出,不修复数据库会为您带来更多工作,而当数据库最终修复时,这些工作将被丢弃?
  • 我不完全相信这一点,但是,考虑到我目前完成这个项目的时间限制,我不能耽搁修复它需要
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多