【问题标题】:Inner Join in Specific Sql Query to Linq C#特定 Sql 查询中的内部联接到 Linq C#
【发布时间】:2014-11-17 15:49:19
【问题描述】:

如何将此 sql 转换为 Csharp linq 代码?


Select * From CsRecognitions Where Id = 499

Select * From CsRecognitionNodes RN
Inner Join CsTreeNodes TN ON RN.NodeId = TN.Id
Where RecognitionId = 499

这些是我的课;


    [Table("CsRecognitions")]
    public class Recognition : Entity
    {
        public virtual Tree Tree { get; set; }

        public virtual int? TreeId { get; set; }

        public virtual Tree MainTree { get; set; }

        public virtual int? MainTreeId { get; set; }

        public virtual ICollection Nodes { get; set; }

        //...
    }

    [Table("CsTreeNodes")]
    public class TreeNode : FullAuditedEntity
    {
        public virtual int TreeId { get; set; }

        [ForeignKey("TreeId")]
        public virtual Tree Tree { get; set; }

        public virtual int? MainNodeId { get; set; }

        //...
    }

    [Table("CsRecognitionNodes")]
    public class RecognitionNode : Entity
    {
        public virtual long RecognitionId { get; set; }

        [ForeignKey("NodeId")]
        public virtual TreeNode Node { get; set; }

        public virtual int NodeId { get; set; }

        [ForeignKey("MainNodeId")]
        public virtual TreeNode MainNode { get; set; }

        public virtual int MainNodeId { get; set; }

        //...
    }

这是我目前的解决方案...但是正如您所见,如果 query.ToList() 会获取太多项目,程序会变慢...

if (input.TreeNodeId.HasValue)
{
    List<long> recognitionNodeIds = _recognitionNodeRepository.GetAll()
                 .Where(rn => rn.CreationTime >= input.StartDate && rn.MainNodeId == input.TreeNodeId.Value)
                 .Select(recognitionNode => recognitionNode.RecognitionId)
                 .ToList();

    List<Recognition> recognitions = query.ToList();

    // recognitions count may be up to 300,000 etc...
    foreach (Recognition recognition in recognitions)
    {
        if (recognitionNodeIds.Contains(recognition.Id))
        {
              recognitionsFiltered.Add(recognition);
        }
    }

    actualResult = recognitionsFiltered;
}

@更新 1: 这是我到目前为止所做的;


                //var asd = _recognitionNodeRepository.GetAll().Join(_treeNodeRepository.GetAll(), x => x.NodeId, y => y.Id, (x, y) => new
                //                                                                                          {
                //                                                                                              RecognitionNode = x,
                //                                                                                              TreeNode = y
                //                                                                                          }).Where(x => x.RecognitionNode.RecognitionId == 9);

【问题讨论】:

  • 你应该可以在你的 linq 查询中使用Contains()
  • .GetAll() 是否返回 IQuerable
  • @Magnus:是的,它返回 IQuerable...
  • @Rhumborl:我不明白 :(

标签: c# sql-server linq inner-join


【解决方案1】:
//first line: 
recognitions.Where(r => r.Id == 499)
//second line, handwritten so don't take it word for word
CsRecognitionNodes.Join(CsTreeNodes, x => x.NodeId, y => y.Id, (x, y) => new { CsRecognitionNodes = x, CsTreeNodes = y}).Where(x => x.CsRecognitionNodes.RecognitionId == 499);

对于您当前的解决方案,consider converting your recognitionNodeIds to a HashSet

当您使用 Hashset 进行包含时,访问时间将是恒定的。现在使用您的列表,您正在遍历所有的识别节点 ID 以查找识别 ID,这肯定会使事情变慢(在您的 foreach 循环中循环)。

【讨论】:

  • 感谢您的回答...但是我不能像“CsRecognitionNodes”这样直接写表名...我更新了我的问题(更新1与您的查询类似)...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多