Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I have been working on an ASP.NET MVC app using Entity Framework. Also, it's my first time developing an ASP.NET MVC app. I have been struggling (close to a month of trying and googling) to write a linq query to display results in jQuery datatable for the below SQL query. It involves various left joins and some columns have null values. It would be great if someone could help me out on this.

There are 3 databases tables as below
  • Assets
  • Category
  • Term

SQL
SELECT 
    Asset.Name As Name,
    Asset.Type As Type,
    Asset.Parent_Asset As "Parent Asset",
    Cat.Category As Category,
    Cat.Parent_Category As "Parent Category",
    T.BUSINESS_TERM As "Business Term",
    T.SHORT_DESCRIPTION As Description
FROM
    (
        SELECT 
            CH.DISPLAY As Name,
            CH.TYPE AS Type,
            PA.DISPLAY As Parent_Asset,
            CH.CATEGORY_INT_ID
        FROM 
            [Metadata].[dbo].[Asset] CH
            LEFT JOIN [Metadata].[dbo].[Asset] PA 
            ON PA.PARENT_ASSET_ID = CH.ASSET_INT_ID
    ) Asset
    LEFT JOIN 
    (
        SELECT
            CH.DISPLAY AS Category,
            PA.DISPLAY AS Parent_Category,
            CH.CATEGORY_INT_ID AS Category_Id
        FROM
            [METADATA].[dbo].[Category] CH
            LEFT JOIN [METADATA].[dbo].[Category] PA 
            ON PA.PARENT_CATEGORY_ID = CH.CATEGORY_INT_ID
    ) Cat 
    ON Asset.CATEGORY_INT_ID = Cat.Category_Id
    LEFT JOIN [Metadata].[dbo].[Term] T 
    ON T.CATEGORY_INT_ID = Cat.Category_Id


What I have tried:

I have tried stored procedure but get null values in table

Queries by me:
C#
<pre> public ActionResult GetData1()
            {
                //Display for Assets Page
                using (MetadataEntities db = new MetadataEntities())
                {
                    List<Asset> c = db.Assets.ToList();
                    List<Category> ct = db.Categories.ToList();
                    List<Term> t = db.Terms.ToList();

  var subQuery1 = from ch in c
                  join pa in c on ch.ASSET_INT_ID equals pa.PARENT_ASSET_ID into tab1
                  from pa in tab1.DefaultIfEmpty()
    
                  select new Asset
                {
                   DISPLAY =ch.DISPLAY,
                   TYPE = ch.TYPE,
                   parentasset = pa.DISPLAY,
                   CATEGORY_INT_ID = ch.CATEGORY_INT_ID
                  };
    
    
var subQuery2 = from CH in ct
              join PA in ct on CH.CATEGORY_INT_ID equals PA.PARENT_CATEGORY_ID into tab2
              from PA in tab2.DefaultIfEmpty()
              select new Category
            {
               DISPLAY = CH == null ? string.Empty : CH.DISPLAY,
               ParentCategory = PA == null ? string.Empty : PA.DISPLAY,
               CATEGORY_INT_ID = CH.CATEGORY_INT_ID
             };
    
var mainQuery = from tab1 in subQuery1
                join Cat in subQuery2 on tab1.CATEGORY_INT_ID equals Cat.CATEGORY_INT_ID                                                                                         
                join term in t on Cat.CATEGORY_INT_ID equals term.CATEGORY_INT_ID 
                                    
                select new Asset
           {
                 DISPLAY = tab1 == null ? string.Empty : tab1.DISPLAY,
                 TYPE = tab1 == null ? string.Empty : tab1.TYPE,
                 parentasset = tab1 == null ? string.Empty : tab1.parentasset,
                 assetcategory = Cat == null ? string.Empty : Cat.DISPLAY,
                 parentcategory = Cat == null ? string.Empty : Cat.ParentCategory,
                 bterm = term == null ? string.Empty : term.BUSINESS_TERM,
                SHORT_DESCRIPTION = term == null ? string.Empty : term.SHORT_DESCRIPTION
            };
    
    
 
                    return Json(new { data = mainQuery }, JsonRequestBehavior.AllowGet);
                }
    
    
            }


It returns 44,557 entries instead of 56932
Posted
Updated 13-May-20 14:14pm
v3

1 solution

You can start by simplifying your SQL query - there's no need for the nested sub-queries:
SQL
SELECT 
    A.DISPLAY As Name,
    A.TYPE As Type,
    PA.DISPLAY As "Parent Asset",
    CH.DISPLAY As Category,
    PC.DISPLAY As "Parent Category",
    T.BUSINESS_TERM As "Business Term",
    T.SHORT_DESCRIPTION As Description
FROM
    [Metadata].[dbo].[Asset] A
    LEFT JOIN [Metadata].[dbo].[Asset] PA 
    ON PA.PARENT_ASSET_ID = A.ASSET_INT_ID
    LEFT JOIN [METADATA].[dbo].[Category] CH
    ON CH.Category_Id = A.CATEGORY_INT_ID
    LEFT JOIN [METADATA].[dbo].[Category] PC 
    ON PC.PARENT_CATEGORY_ID = CH.CATEGORY_INT_ID
    LEFT JOIN [Metadata].[dbo].[Term] T 
    ON T.CATEGORY_INT_ID = CH.CATEGORY_INT_ID
;
Assuming you have proper navigation properties in place in your Entity Framework models, it should be as simple as:
C#
var result = yourDbContext.Assets
    .Select(asset => new
    {
        Name = asset.Display,
        Type = asset.Type,
        Parent_Asset = asset.ParentAsset.Display,
        Category = asset.Category.Display,
        Parent_Category = asset.Category.ParentCategory.Display,
        Business_Term = asset.Category.Term.Business_Term,
        Description = asset.Category.Term.Short_Description
    })
    .ToList();
 
Share this answer
 
Comments
Maciej Los 13-May-20 14:59pm    
I knew it! I felt it! I was almost 100% sure that you answer this question. ;)
5ed!
Ravi 1001 13-May-20 19:49pm    
It doesn't work. Category_Int_Id is Foreign Key in Assets Table and Term_Int_ID is foreign Key in Assets Table. Hope there is any other solution
Richard Deeming 14-May-20 6:10am    
That description doesn't match the SQL query from your question. There, the Term table is joined to the Category table on the category ID column.

If it should be joined to the asset instead, it's a simple update. In SQL:
LEFT JOIN [Metadata].[dbo].[Term] T 
ON T.TERM_INT_ID = A.TERM_INT_ID

and in the LINQ query:
Business_Term = asset.Term.Business_Term,
Description = asset.Term.Short_Description

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900