简体   繁体   中英

Inner Join in Specific Sql Query to Linq C#

How can I convert this sql to Csharp linq code ?


Select * From CsRecognitions Where Id = 499

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

These are my classes;


    [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; }

        //...
    }

Here is my current solution... But as you see if query.ToList() will get too many items, program will be getting slower...

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;
}

@UPDATE 1: Here is what I've done so far;


                //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);
//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);

For your current solution, consider converting your recognitionNodeIds to a HashSet .

When you do Contains with a Hashset, it'll be constant time for access. Right now with your List, you're iterating through all the recognitionNodeIds to look for recognition.Id, which is definitely making things slower (loop within your foreach loop).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM