2

尝试使用 Linq 加入。我应该使用什么?左连接还是右连接?

    FIRST LIST                                 SECOND LIST

APPLICANT_ID|Applicant_Name| NOTES | |APPLICANT_ID|Applicant_Name  | NOTES |
      1     |  RAY HEAVENS | Note1 | |    2       |  BEN TULFO     | NoteA 
      2     |  BEN TULFO   | Note2 | |    3       |  ERNIE BARON   | NoteB 
      3     |  ERNIE BARON | Note3 | | 
      4     |   SUPERMAN   | Note4 | |
      5     |  MARK LAPID  | Note5 | |  

期望的输出:

APPLICANT_ID | Applicant_Name |   NOTES 
-------------+----------------+---------
      1      |   RAY HEAVENS  |  Note1
      2      |   BEN TULFO    |  NoteA
      3      |   ERNIE BARON  |  NoteB
      4      |   SUPERMAN     |  Note4
      5      |   MARK LAPID   |  Note5

这是我在控制器中的代码:

 var applicantList = (from a in db.Profiles 
                      where a.isDeleted == false
                      select a ).ToList();

 var GetNewNotes = (from a in db.ProfilesNotes 
                    where a.isDeleted == false
                    select a).ToList();

 var lst = (from lst1 in applicantList 
            where !GetNewNotes.Any(x => x.APPLICANT_ID == lst1.APPLICANT_ID )
            select lst1).ToList();

ViewBag.updatedNotes = lst;

我希望有人可以推荐我使用什么或做什么。

先感谢您。

4

2 回答 2

1

I would go for an inner join with .Join():

var lst = applicantList.Join(GetNewNotes,
    (a) => a.APPLICANT_ID,
    (n) => n.APPLICANT_ID,
    (a, n) => return new
    {
        a.APPLICANT_ID,
        a.Applicant_Name,
        n.Notes
    });

/*
lst:
2 | BEN TULFO   | NoteA,
3 | ERNIE BARON | NoteB
*/

As a side note, is there any reason your second table contains ApplicantName? Why not keep this in Applicant table only?

EDIT: After re-reading the question, I realized that you need the unmatched entries from the left list too. So, that should be left outer join instead, which you achieve with .GroupJoin() and .SelectMany():

var lst = applicantList.GroupJoin(GetNewNotes,
    (a) => a.Id,
    (n) => n.Id,
    (a, n) => new
    {
        Id = a.Id,
        Name = a.Name,
        Notes = a.Notes,
        ApplicantNotes = n
    })
    .SelectMany(
        g => g.ApplicantNotes.DefaultIfEmpty(),
        (g, applicantNotes) => new
        {
            Id = g.Id,
            Name = g.Name,
            Notes = applicantNotes?.Notes ?? g.Notes
        });

/*
lst:
1 | RAY HEAVENS | Note1
2 | BEN TULFO   | NoteA
3 | ERNIE BARON | NoteB
4 | SUPERMAN    | Note4
5 | MARK LAPID  | Note5
*/
于 2019-03-01T06:33:16.157 回答
1

这是一个奇怪的映射结构。从结构上看,它看起来像 1 对 0..1,但在概念上它看起来应该是 1 对多。对于一对多,我希望表结构更像:

申请人(申请人 ID | 姓名)

申请者注(申请者注ID |申请者ID |注)

这将在 EF 中映射,例如:

public class Applicant
{
    public int ApplicantId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<ApplicantNote> { get; set; } = new List<ApplicantNote>();
}

public class ApplicantNote
{
    public int ApplicantNoteId { get; set; }
    public virtual Applicant Applicant { get; set; }
}

public class ApplicantConfig : EntityTypeConfiguration<Applicant>
{
    public ApplicantConfig()
    {
        ToTable("Applicant");
        HasKey(x => x.ApplicantId);

        HasMany(x => x.ApplicantNotes)
            .WithRequired(x => x.Applicant)
            .Map(x => x.MapKey("ApplicantId"));
    }
}
public class ApplicantNoteConfig : EntityTypeConfiguration<ApplicantNote>
{
    public ApplicantNoteConfig()
    {
        ToTable("ApplicantNote");
        HasKey(x => x.ApplicantNoteId);
    }
}

你所拥有的更像是一个包含注释的申请人表,但是还有一个额外的表可以容纳一个额外的额外注释。

申请人(申请人 ID | 姓名 | 备注)

ExtraApplicantNote (ApplicantId | Note) // 姓名不是必需的。

在 1 到 0..1 中看起来像:

public class Applicant
{
    public int ApplicantId { get; set; }
    public string Name { get; set; }
    public string Note { get; set; }

    public ExtraApplicantNote ExtraApplicantNote { get; set; }
}

public class ExtraApplicantNote
{
    public int ApplicantId { get; set; }
    public string Note { get; set; }
    public virtual Applicant Applicant { get; set; }
}

public class ApplicantConfig : EntityTypeConfiguration<Applicant>
{
    public ApplicantConfig()
    {
        ToTable("Applicant");
        HasKey(x => x.ApplicantId);

        HasOptional(x => x.ExtraApplicantNote)
            .WithRequired(x => x.Applicant);
    }
}
public class ExtraApplicantNoteConfig : EntityTypeConfiguration<ExtraApplicantNote>
{
    public ExtraApplicantNoteConfig()
    {
        ToTable("ExtraApplicantNote");
        HasKey(x => x.ApplicantId);
    }
}

这会将这个额外的申请人注释记录作为可选的关联实体加入到申请人中。选择实体图时:

var applicant = context.Applicants
    .Include(x => x.ExtraApplicantNote)
    .Single(x => x.ApplicantId == applicantId);

例如...然后通过applicant.Note和访问注释,applicant?.ExtraApplicantNote.Note以说明额外的申请人注释是可选的。

要生成所有笔记及其申请人详细信息的输出,一对多结构的生成要简单得多:

var notes = context.ApplicantNotes.Select(x => new 
  {
    x.Applicant.ApplicantId,
    x.Applicant.Name,
    x.Note
  }).ToList();

用 1 到 0..1 做同样的事情需要更多的参与:

var notes = context.Applicants.Select(x => new 
  {
    x.ApplicantId,
    x.Name,
    x.Note
  }).Union(context.ExtraApplicantNotes.Select(x => new
  {
    x.ApplicantId,
    x.Applicant.Name,
    x.Note
  })).ToList();

这包括首先从第一个表中提取注释,然后使用联合从第二个表中的可选记录中连接相同的详细信息。

** 编辑 ** 抱歉,我重新阅读了这个问题,您希望第二个表覆盖第一个表。

在这种情况下,类似于上面:

var notes = context.ExtraApplicantNotes.Select(x => new 
  {
    x.ApplicantId,
    x.Applicant.Name,
    x.Note
  }).Union(context.Applicants
  .Where(x => x.ExtraApplicant == null)      
  .Select(x => new
  { 
    x.ApplicantId,
    x.Name,
    x.Note
  })).ToList();
于 2019-03-01T06:29:25.893 回答