How to program sql query with inner join in ASP.Net MVC? - c#

I'm trying to do a LINQ statement using three database tables for my third dropdownlist. Below are my codes but I get an error (for my third dropdownlist) when I choose a cluster in the second dropdownlist.
**//SECTORS**
public JsonResult GetSectors()
{
using (SAMPDBEntities context = new SAMPDBEntities())
{
var ret = context.SECLIBs
.Select(x => new { x.seccd, x.unitacro }).ToList();
return Json(ret, JsonRequestBehavior.AllowGet);
}
}
**//CLUSTERS**
public JsonResult GetCluster(string seccd)
{
using (SAMPDBEntities context = new SAMPDBEntities())
{
var ret = context.CLUSLIBs
.Where(x => x.seccd.Contains(seccd))
.Select(x => new { x.cluscd, x.unitdesc }).ToList();
return Json(ret, JsonRequestBehavior.AllowGet);
}
}
**//EMPLOYEES**
public JsonResult GetEmployee(string cluscd)
{
using (SAMPDBEntities context = new SAMPDBEntities())
{
var ret = context.UNILIBs
.Where(a => a.cluscd.Contains(cluscd))
.Include(x => x.PPSAs.Select(y => y.EMPFILE.empno))
.ToList();
return Json(ret, JsonRequestBehavior.AllowGet);
}
}
Here's my error:
A specified Include path is not valid. The EntityType 'SAMPDBModel.EMPFILE' does not declare a navigation property with the
name 'empno'.
and here's the SQL query (for my third dropdownlist):
SELECT DISTINCT e.empno, e.lname, e.fname, e.mname, c.cluscd
FROM SECLIB a
INNER JOIN CLUSLIB b
ON a.seccd = b.seccd
INNER JOIN UNILIB c
ON b.cluscd = c.cluscd
INNER JOIN PPSA d
ON c.unitcode = d.unitcd
INNER JOIN EMPFILE e
ON d.empno = e.empno
WHERE e.empstat = 1 AND c.cluscd = #cluscd
I need to do a cascading dropdownlist and I need to show the list of employees based on the selected sector and cluster. How can I do that using multiple tables? Please help me. Thanks in advance!

This should be an issue of not specifying the correct respective name that generated from EDMX. Please Can you check the "EMPFILE" Class that generated from Entity Framework It should have similar name with different case sensitive word.
When querying in SQL it does not bother with case sensitivity. But C# is case sensitive language.
And its better if you can post the "EMPFILE" class and database table here.

Related

LINQ troubles in C# using Entity Framework

I have a few tables and this is what I need to achieve.
This gets all the rows from one table
var FRA = from prod in _cctDBContext.Fra
where prod.ActTypeId == 1
From within that, I get all the rows where ActTypeID.
Then I need to query another table from with the ID's get from that
foreach (var item in FRA)
{
var FRSA = _cctDBContext.Frsa
.Select(p => new { p.Fraid, p.Frsa1,
p.Frsaid, p.CoreId,
p.RelToEstId, p.ScopingSrc,
p.Mandatory })
.Where(p => p.Fraid == item.Fraid)
.ToList();
}
I then need to push each one of these to Entity Framework. I usually do it this way:
foreach (var item in FRA)
{
var FinanicalReportingActivity = new FinancialReportingActivity { FinancialReportingActivityId = item.Fraid, ScopingSourceType = item.ScopingSrc, Name = item.Fra1, MandatoryIndicator = item.Mandatory, WorkEffortTypeId = 0 };
_clDBContext.FinancialReportingActivity.AddRange(FinanicalReportingActivity);
}
But because I have used 2 for each loops, I cannot get the variables to work because I cannot find a way to get local variables as the entity context.
Can anyone think of a better way to code this?
Thanks
It looks like you can do this as a single join:
var query =
from prod in _cctDBContext.Fra
where prod.ActTypeId == 1
join p in _cctDBContext.Frsa on prod.Fraid equals p.Fraid
select new
{
p.Fraid,
p.Frsa1,
p.Frsaid,
p.CoreId,
p.RelToEstId,
p.ScopingSrc,
p.Mandatory
};
It looks like you are loading data from one set of entities from one database and want to create matching similar entities in another database.
Navigation properties would help considerably here. Frsa appear to be a child collection under a Fra, so this could be (if not already) wired up as a collection within the Fra entity:
Then you only need to conduct a single query and have access to each Fra and it's associated Frsa details. In your case you look to be more interested in the associated FRSA details to populate this ReportingActivity:
var details = _cctDBContext.Fra
.Where(x => x.ActTypeId == 1)
.SelectMany(x => x.Frsa.Select(p => new
{
p.Fraid,
p.Frsa1,
p.Frsaid,
p.CoreId,
p.RelToEstId,
p.ScopingSrc,
p.Mandatory
}).ToList();
though if the relationship is bi-directional where a Fra contains Frsas, and a Frsa contains a reference back to the Fra, then this could be simplified to:
var details = _cctDBContext.Frsa
.Where(x => x.Fra.ActTypeId == 1)
.Select(p => new
{
p.Fraid,
p.Frsa1,
p.Frsaid,
p.CoreId,
p.RelToEstId,
p.ScopingSrc,
p.Mandatory
}).ToList();
Either of those should give you the details from the FRSA to populate your reporting entity.

Write query in Entity Framework

I have a query which I ran successfully in SQL Server Management Studio, which returns the table values shown in the screenshot
The query I used is:
SELECT tcoid, COUNT(*) ownleasetank
FROM TankProfile
WHERE ownleasetank = 3
GROUP BY tcoid
Now I'm using Entity Framework to make things easier in my sample project.
I used this method to return the table values as array object:
public async Task<Object> GetLeaseInformationPrincipal()
{
ISOTMSEntities context = new ISOTMSEntities();
var testleaseinfo = from d in context.TankProfiles
join f in context.TankOperators
on d.tcoid equals f.tcoId
where (d.ownleasetank == 3)
select new { f.tcoName, d.ownleasetank } into x
group x by new { x.tcoName } into g
select new
{
tconame = g.Key.tcoName,
ownleasetank = g.Select(x => x.ownleasetank).Count()
};
return testleaseinfo.ToList();
}
but it is not working properly. I also tried other ways, when I use where and groupby method in Entity Framework it doesn't working properly for me.
Does anybody know the solution for this?
It's very simple with LINQ methods:
context.TankProfiles
.Where(t => t.ownleasetank = 3)
.GroupBy(t => t.tcoid)
.Select(g => new {g.Key, g.Count()})
.ToArray();
I have no idea why in your C# version of the query you have such opeartions such join, while your SQL query is very simple. You have to rethink that :)
var c = from t in context.TankProfile
where t.ownleasetank == 3
group t by t.tcoid into g
select new { tcoid=g.Key, ownleasetank=g.Select(x => x.ownleasetank).Count() };
return c.ToList();

How to use SQL Joins in Web API

I need to pass SQL Query(with Joins) as parameter to my API and retrun the results. But the result is dependent on the using the below code. I there any way to get this fixed. Please advise.
Expected results should be all the columns from the query into var users variable.
public IHttpActionResult retData()
{
using (var context = new DBModel())
{
var users = context.Database.SqlQuery<portal_testcase_scn>("SELECT *,Portal_Version.build FROM [portal_testcase_scn] inner join Portal_Version on [portal_testcase_scn].row_num=Portal_Version.row_num").ToList();
return Ok(users);
}
}
You can use Linq.
using (var context = new DBModel())
{
List<object> users = (from c in context.portal_testcase_scn
join d in context.Portal_Version
on c.row_num equals d.row_num
select new {
build=d.build,
}).ToList();
return Ok(users);
}

Avoiding for loops to bring table related information for grid display

I have the following database schema for which I am developing the screen for it.
I want to display the information in a grid ,for example Desc should be repeated in more than one row and for each row there has to be columns from
tableC,tableB and tableA related information.
Right now I am getting every table in the controller layer using linq "Include" related entities and using many foreach loops I am getting the customTable class created and then binding it to the kendo grid.
foreach(var a in table C)
{
foreach(var b in tableB)
{
CustomTable c = new CustomTable {
tableDesc = b.Desc,
tableBDesc = a.Desc
}
}
}
class CustomTable
{
public string tableDDesc{get;set;}
public string tableBDesc {get;set;}
}
I am thinking is there any better approach for this /Linq syntax to build the customClass in Data access layer itself. Any inputs please?
If you using EF you can do it this way:
_context.TableC.Select(x => x.TableB)
.Select(x => new CustomTable
{
tableDesc = x.TableC.Desc,
tableBDesc = x.Desc
});
This code will generate SELECT with JOIN and return you List of your CustomTable objects.
It will get from TableB only rows that have filled tableC_id field (NOT NULL).
How about using link projects to bring back results as CustomTable class. Something like this
var results = (from tableC in context.TableCs
from tableB in context.TableBs
where tableB.Id == tableC.Id
select new { tableDDesc = tableB.Description, tableBDesc = tableC.Description }
).ToList();
results.ForEach(obj => new CustomTable{tableDDesc = obj.tableDDesc, tableBDesc = obj.tableBDesc});
you can remove the where tableB.Id == tableC.Id if not needed

Linq: let Count result into a specified column

I've got a table Installation which can contains one or many Equipements.
And for functionnal reasons, I've overwritten my table Installation and added a field NbrEquipements.
I want to fill this field with Linq, but I'm stuck...
Due to special reasons, there is no relation between these to tables. So, no Installation.Equipements member into my class. Therefore, no Installation.Equipements.Count...
I'm trying some stuff. Here is my code:
var query = RepoInstallation.AsQueryable();
// Some filter
query = query.Where(i => i.City.RegionId == pRegionId));
int?[] etatIds = { 2, 3 };
query = (from i in query
select new Installation
{
NbrEquipements= (from e in RepoEquipement.AsQueryable()
where e.InstallationSpecialId == i.SpecialId
&& (etatIds.Contains(e.EquEtat))
select e.SasId
).Count()
});
But with this try, I got this error:
The entity or complex type 'myModel.Installation' cannot be constructed in a LINQ to Entities query
I've tried some other stuff but I'm always turning around...
Another thing that can be useful for me: It would be great to fill a field called Equipements which is a List<Equipement>.
After that, I would be able to Count this list...
Is it possible ?
Tell me if I'm not clear.
Thanks in advance.
Here is the final code:
//In the class:
[Dependency]
public MyEntities MyEntities { get; set; }
//My Methode code:
var query = MyEntities .SasInstallations.AsQueryable();
// Some filter
query = query.Where(i => i.City.RegionId == pRegionId));
var liste = new List<Installation>();
var queryWithListEquipements =
from i in query
select new
{
Ins = i,
EquipementsTemp = (from eq in MyEntities.Equipements.AsQueryable()
where eq.SpecialId == i.SpecialId
&& (etatIds.Contains(eq.SasEquEtat))
select eq
).ToList()
};
var listWithListEquipements = queryWithListEquipements.ToList();
foreach (var anonymousItem in listWithListEquipements)
{
var ins = anonymousItem.Ins;
ins.Equipements = anonymousItem.EquipementsTemp;
ins.NumberEquipements = ins.Equipements.Count();
liste.Add(ins);
}
return liste;
By the way, this is very very fast (even the listing of Equipements). So this is working exactly has I wished. Thanks again for your help everyone!
Use an anonymous type. EF does not like to instantiate entity classes inside a query.
var results = (from i in query
select new
{
NbrEquipements= (from e in RepoEquipement
where e.InstallationSpecialId == i.SpecialId
&& (etatIds.Contains(e.EquEtat))
select e.SasId
).Count()
})
.ToList();
Notice how I used select new instead of select new Installation.
You can then use the data inside the list (which is now in memory) to create instances of type Installation if you want like this:
var installations = results.Select(x =>
new Installation
{
NbrEquipements = x.NbrEquipements
}).ToList();
Here is how to obtain the list of equipment for each installation entity:
var results = (from i in query
select new
{
Installation = i,
Equipment = (from e in RepoEquipement
where e.InstallationSpecialId == i.SpecialId
&& (etatIds.Contains(e.EquEtat))
select e).ToList()
})
.ToList();
This will return a list of anonymous objects. Each object will contain a property called Installation and another property called Equipment (which is a list). You can easily convert this list (of anonymous objects) to another list of whatever type that you want.

Categories

Resources