【问题标题】:Linq Joins only working when all tables have dataLinq Joins 仅在所有表都有数据时才起作用
【发布时间】:2016-04-08 01:14:39
【问题描述】:

您可以在下面找到我的问题。当“DocentenCompetenties”和“DocentenLocaties”都被填写时,我的视图只会循环遍历数据。这是一个问题,因为即使其中一个没有任何数据,我也希望能够循环它们

var ShowCompetenties = from d in db.Docent
      join dc in db.DocentenCompetenties on d.DocentID equals dc.DocentID
      join c in db.Competenties on dc.CompetentiesID equals c.CompetentiesID
      join dl in db.DocentenLocaties on d.DocentID equals dl.DocentID
      where d.DocentID == id
      join l in db.Locaties on dl.LocatieID equals l.LocatieID
      select new ShowCompetenties { Docenten = d, Competenties = c, DocentenCompetenties = dc, DocentenLocaties = dl, Locaties = l };

更新

当前错误: App_Web_xp01otas.dll 中出现“System.NullReferenceException”类型的异常,但未在用户代码中处理 附加信息:对象引用未设置为对象的实例。

    var id = Convert.ToInt32(Session["id"]);
    var LeftShowCompetenties = from d in db.Docent
       join g1 in db.DocentenCompetenties on d.DocentID equals g1.DocentID into group1
       from dc in group1.DefaultIfEmpty()                                    
       join c in db.Competenties on dc.CompetentiesID equals c.CompetentiesID
       where d.DocentID == id                          
       select new ShowCompetenties { Docenten = d, Competenties = c, DocentenCompetenties = dc};


    var RightShowCompetenties = from d in db.Docent                                         
        join g3 in db.DocentenLocaties on d.DocentID equals g3.DocentID into group3      from dl in group3.DefaultIfEmpty()
        where d.DocentID == id
        join l in db.Locaties on dl.LocatieID equals l.LocatieID
        select new ShowCompetenties { Docenten = d, Locaties = l, DocentenLocaties = dl };



    var ShowCompetenties = LeftShowCompetenties.Union(RightShowCompetenties);

查看

<h4>Competenties</h4>
@foreach (var item in Model)
{
            if(@item.DocentenCompetenties != null && @item.DocentenCompetenties.DocentID.ToString() != null) { 
            @item.Competenties.Name @Html.ActionLink("Delete", "DeleteCompetenties", new { id = item.DocentenCompetenties.DocentenCompetentiesID })
}

 <h4>Docenten</h4>
 @foreach (var item in Model)
 {
      if(@item.DocentenLocaties != null && @item.DocentenLocaties .DocentID.ToString() != null) 
        {
            @item.Locaties.Name
        }
}

【问题讨论】:

  • 我正在使用 @foreach(var item in Model) { @item.Locaties.Name } 我尝试但它失败了。我应该重写查询吗?
  • 不言而喻,如果您必须在 LINQ 中进行联接,则可能有问题 - 至少,实体之间缺少关系。最坏的情况是,LINQ 被用作 SQL 的替代品(它不是),并且整个连接都应该用 VIEW 代替。至少,在您的模型/映射中创建适当的关系

标签: c# asp.net linq join


【解决方案1】:

您正在以这种方式进行内部联接。

听起来您实际上想要进行外部联接。 试试这个:

var ShowCompetenties = from d in db.Docent
  join g1 in db.DocentenCompetenties on d.DocentID equals g1.DocentID into group1
  from dc in group1.DefaultIfEmpty()

  join g2 in db.Competenties on dc.CompetentiesID equals g2.CompetentiesID into group2
  from c in group2.DefaultIfEmpty()

  join g3 in db.DocentenLocaties on d.DocentID equals g3.DocentID into group3
  from dl in group3.DefaultIfEmpty()

  where d.DocentID == id
  join l in db.Locaties on dl.LocatieID equals l.LocatieID
  select new ShowCompetenties { Docenten = d, Competenties = c, DocentenCompetenties = dc, DocentenLocaties = dl, Locaties = l };

但是,如果您希望进行完全外连接,这只是一个左外连接。您必须先进行左外连接,然后进行右外连接,最后合并(与Union())两者。

编辑 根据 cmets,关于您在 UNION 之后遇到的错误:

    var id = Convert.ToInt32(Session["id"]);
        var LeftShowCompetenties = from d in db.Docent
            join g1 in db.DocentenCompetenties on d.DocentID equals g1.DocentID into group1
            from dc in group1.DefaultIfEmpty()                                    
            join c in db.Competenties on dc.CompetentiesID equals c.CompetentiesID
            where d.DocentID == id                          
            select new ShowCompetenties { Docenten = d, Competenties = c, Locaties = null, DocentenCompetenties = dc, DocentenLocaties = null};


    var RightShowCompetenties = from d in db.Docent                                         
           join g3 in db.DocentenLocaties on d.DocentID equals g3.DocentID into group3
           from dl in group3.DefaultIfEmpty()
           where d.DocentID == id
           join l in db.Locaties on dl.LocatieID equals l.LocatieID
           select new ShowCompetenties { Docenten = d, Competenties = null, Locaties = l, DocentenCompetenties = null, DocentenLocaties = dl };



   var ShowCompetenties = LeftShowCompetenties.Union(RightShowCompetenties);

(检查构造函数中添加的Locaties = nullCompetenties = null。)

查看

if (@item.DocentenCompetenties != null){}
if (@item.DocentenLocaties!= null){}

【讨论】:

  • 检查这个:msdn.microsoft.com/en-us/library/bb397908.aspx 它提供了关于这一切的更多解释。对于创建正确的连接:您基本上在连接中切换表。如果您想了解更多详细信息,这里有很多示例。
  • “DocentenAlumniAPP.Models.ShowCompetenties”类型出现在单个 LINQ to Entities 查询中的两个结构不兼容的初始化中 我在执行示例时遇到错误
  • 听起来你选择的构造函数在左连接和右连接中是不同的。 (该错误通常在Union() 期间抛出)您可以发布完整的查询吗?
  • 啊,是的,您“必须”使用类似的构造函数。我将使用应该有效的示例更新我的答案。编辑:更新它。
  • @SaraBarreraRiano - 此时发生错误,因为 item.DocentenCompetenties.DocentID 为空时无法使用 ToString() 方法。您基本上说将 DocentID 转换为字符串,如果它为空,则无法执行此操作。它试图在您之前执行此操作,然后检查它是否为空。取下 ToString() 进行此项检查。
【解决方案2】:

如果您设置了导航属性,则左连接会容易得多:

var ShowCompetenties =
  from d in db.Docent
  where d.DocentID == id
  from dc in d.DocentenCompetenties.DefaultIfEmpty()
  let c = dc.Competenty
  from dl in d.DocentenLocaties.DefaultIfEmpty()
  let l = dl.Locaty
  select new ShowCompetenties {
    Docenten = d,
    Competenties = c,
    DocentenCompetenties = dc,
    DocentenLocaties = dl,
    Locaties = l };

【讨论】:

  • 我认为我的连接正在工作,我现在只是在努力解决这个错误 App_Web_q05ilzt1.dll 中发生了“System.NullReferenceException”类型的异常,但未处理在用户代码中
  • @SaraBarreraRiano 如果您必须使用连接,那么 LINQ 映射将被破坏。如果您必须手动使用连接实体,则使用 ORM 没有任何好处,但是这会导致很多问题 - 关系代码以连接的形式分布在所有控制器中,而它应该是DbContext 的配置中的几行代码
  • 所以这是一个更好的解决方案?
猜你喜欢
  • 1970-01-01
  • 2019-11-17
  • 2013-08-11
  • 2016-10-19
  • 2020-10-18
  • 2021-12-31
  • 1970-01-01
  • 2013-06-29
  • 1970-01-01
相关资源
最近更新 更多