SQL Server : INNER JOIN writes out things two times - c#

Here is my SQL query
select
tblUnderKategori.fldKategori,
tblUnderKategori.fldNavn,
tblUnderKategori.fldBillede,
tblKategori.fldId,
tblKategori.fldKategoriNavn
from
tblUnderKategori
inner join
tblKategori on tblUnderKategori.fldKategori=2
And as you can see I need everything where my fldKategori = 2, and so it does, but it writes it out x2 times.
And here is my backend code for the place where it needs to be displayed
katFac objKat = new katFac();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack && !string.IsNullOrEmpty(Request.QueryString["id"]))
{
foreach (DataRow item in objKat.GetUnderkatByKat(Convert.ToInt32(Request.QueryString["id"])).Rows)
{
litUnderkategori.Text += item["fldNavn"].ToString() + "<br /><br />";
}
}
}
I just can't seeme to figure out the problem so anyone please help
Thank you in advance! :)

You are creating a karthesian product here as your join is missing the condition that actually joins the two tables together.
Try to use this:
select
tblUnderKategori.fldKategori,
tblUnderKategori.fldNavn,
tblUnderKategori.fldBillede,
tblKategori.fldId,
tblKategori.fldKategoriNavn
from
tblUnderKategori
inner join tblKategori
on tblUnderKategori.fldKategori = tblKategori.fldId
where tblUnderKategori.fldKategori=2
This assumes that tblUnderKategori.fldKategori contains the ID of the parent category.

A JOIN joins two tables, and you must provide the common column. If you also want to filter out certain values, add a WHERE clause afterwards. Also, you don't actually have to SELECT the fields used for matching and joining if you don't explicitly want to read them later on.
select
tblUnderKategori.fldNavn,
tblUnderKategori.fldBillede,
tblKategori.fldKategoriNavn
from tblUnderKategori join tblKategori
on tblUnderKategori.fldKategori = tblKategori.fldId
where
tblUnderKategori.fldKategori = 2

ON clause specifies on which column that tables should be joined, condition should be included in WHERE clause. Try Something like this:
SELECT
tblUnderKategori.fldKategori,
tblUnderKategori.fldNavn,
tblUnderKategori.fldBillede,
tblKategori.fldId,
tblKategori.fldKategoriNavn
FROM tblUnderKategori
INNER JOIN tblKategori
ON tblUnderKategori.[some key column] = tblKategori.[corresponding key column]
WHERE tblUnderKategori.fldKategori=2

You SQL statement is missing a field to JOIN the tables on. It should be something like this:
select u.fldKategori,
u.fldNavn,
u.fldBillede,
k.fldId,
k.fldKategoriNavn
from tblUnderKategori u
inner join tblKategori k
on u.fldKategori = k.fldId
where u.fldKategori=2
Then you will apply your filter in the the WHERE clause.

Related

Group data and retrieve every line of the grouping with Entity Framework

I was thinking that maybe, once the grouped data are retrieved in the C# part, I would be able loop through the list of items that were grouped.
var res = db.Commandes.Where(t => t.idMatiere == mod.idMatiereChoisie).GroupBy(t => t.UA_idCa);
foreach(var group in res)
{
foreach(var groupedLines in group)
{
// Always a single line, this loop is useless
}
}
It seems the logic applied here is more like SQL than C#: the grouping result in a single line and you won't see all the grouped items.
It's not a problem that I can't overcome
Tactic I will use: instead of grouping, I'll just query all the lines, and then, while looping, I will verify if UA_idCa is different form the previous data and that will means the next "group" has been reached.
But I wonder... How does someone normally do this cleanly, if it's possible?
Do you have to query again to retrieve a group's content?
Or is the "Tactic I will use" closer to what's best?
This problem is a matter of the combination of SQL server AND Entity Framework.
Seems like one of the value in the grouped part (a value that is different for all the line inside the group) must be marked as not null.
Because when looking for what could be a key, entity doesn't give a damn about nullable values : they could be unique, they could be never null, EF won't even check that.
Once it is marked as NOT NULL in the sql part, EF suddenly understand that there could multiple different unique values in the grouped part...
So basically This :
ALTER view [dbo].[Commandes] as
SELECT top(50000000)
isnull(ex.unitAdm, '000') UnitAdm
,c.id as idCahier
,isnull(ex.unitAdm, '000') + cast(c.id as nvarchar(6)) as UA_idCa
,c.NomCahier
,[Qte]
,c.prix as PrixCahier
,sc.id, 0 as idSousCahier /* THIS IS WHAT I COULD NOT COMPLETELY RETRIEVE
because it could be null ? */
,sc.NomCahier as sousCahier
,sc.prix as PrixSC
,m.id as idMatiere
,m.Code
,m.NomMatiere
,ep.id as idEpreuve
,ep.Titre
FROM [CahierExamen] cex
join Cahier c on c.id = cex.Fk_Cahier
join Examen ex on cex.FK_Examen = ex.id
join epreuve ep on ex.FK_Epreuve = ep.id
join Matiere m on ep.FK_Matiere = m.id
left join SousCahier sc on c.id = sc.FK_Cahier
order by code, unitAdm, idCahier
GO
As been changed to this:
ALTER view [dbo].[Commandes] as
SELECT top(50000000)
isnull(ex.unitAdm, '000') UnitAdm
,c.id as idCahier
,isnull(ex.unitAdm, '000') + cast(c.id as nvarchar(6)) as UA_idCa
,c.NomCahier
,[Qte]
,c.prix as PrixCahier
,isnull(sc.id, 0) as idSousCahier /* WOW, NOW EF UNDERSTAND
THERE COULD BE MULTIPLE DIFFERENTS VALUES ONCE DATA ARE GROUPED*/
,sc.NomCahier as sousCahier
,sc.prix as PrixSC
,m.id as idMatiere
,m.Code
,m.NomMatiere
,ep.id as idEpreuve
,ep.Titre
FROM [CahierExamen] cex
join Cahier c on c.id = cex.Fk_Cahier
join Examen ex on cex.FK_Examen = ex.id
join epreuve ep on ex.FK_Epreuve = ep.id
join Matiere m on ep.FK_Matiere = m.id
left join SousCahier sc on c.id = sc.FK_Cahier
order by code, unitAdm, idCahier
GO

Conversion of Sql query to linq

I am trying to convert sql query for select to linq query using EF in MVC but really got stuck with an error.
In SQL I'm able to get 6 records for my query,similarly when I try to convert this to linq it shows some error.
Following is my query in SQL:
SELECT
PurchaseOrderMaster.*, PurchaseOrderDetails.*, Vendor.*,
BusinessUnit.*, InvoiceMaster.*, TenantEmployee.*
FROM
PurchaseOrderMaster
INNER JOIN
PurchaseOrderDetails ON PurchaseOrderMaster.TenantID = PurchaseOrderDetails.TenantID
AND PurchaseOrderMaster.PurchaseOrderNumber = PurchaseOrderDetails.PurchaseOrderNumber
AND PurchaseOrderMaster.PurchaseOrderDate = PurchaseOrderDetails.PurchaseOrderDate
INNER JOIN
InvoiceMaster ON PurchaseOrderMaster.TenantID = InvoiceMaster.TenantID
AND PurchaseOrderMaster.PurchaseOrderNumber = InvoiceMaster.PurchaseOrderNumber
AND PurchaseOrderMaster.PurchaseOrderDate = InvoiceMaster.PurchaseOrderDate
INNER JOIN
BusinessUnit ON PurchaseOrderMaster.TenantID = BusinessUnit.TenantID
AND PurchaseOrderMaster.BusinessUnitID = BusinessUnit.BusinessUnitID
INNER JOIN
TenantEmployee ON PurchaseOrderMaster.TenantID = TenantEmployee.TenantID
INNER JOIN
Vendor ON PurchaseOrderMaster.TenantID = Vendor.TenantID
AND PurchaseOrderMaster.VendorID = Vendor.VendorID
For this query I am able to get 6 records .
And my linq query is:
return (from pom in db.PurchaseOrderMaster
join pod in db.PurchaseOrderDetails on pom.TenantID equals pod.TenantID
where pom.PurchaseOrderNumber == pod.PurchaseOrderNumber && pom.PurchaseOrderDate == pod.PurchaseOrderDate
join inv in db.InvoiceMaster on pom.TenantID equals inv.TenantID
where pom.PurchaseOrderNumber == inv.PurchaseOrderNumber && pom.PurchaseOrderDate == inv.PurchaseOrderDate
join bu in db.BusinessUnit on pom.BusinessUnitID equals bu.BusinessUnitID
join te in db.TenantEmployee on pom.TenantID equals te.TenantID
join v in db.Vendor on pom.TenantID equals v.TenantID
where pom.VendorID == v.VendorID
orderby pom.PurchaseOrderNumber ascending, pom.PurchaseOrderDate descending
select new { pom, pod, inv, bu, te, v }).ToList();
At the time of debugging,following is the error that I'm getting:
{"Invalid column name 'invoiceMasterModel_TenantID'.\r\nInvalid column name 'invoiceMasterModel_PurchaseOrderNumber'.\r\nInvalid column name 'invoiceMasterModel_PurchaseOrderDate'.\r\nInvalid column name 'invoiceMasterModel_InvoiceNumber'.\r\nInvalid column name 'invoiceMasterModel_InvoiceDate'.\r\nInvalid column name 'tenantEmployeeModel_TenantID'.\r\nInvalid column name 'tenantEmployeeModel_EmployeeID'."}
Inside Invoice Table it is not able to find some of the columns and hence throwing the error according to me..
I tried with many possible ways but was unable to solve this.
Any ideas..?
Problem was with my Entity.
What I did is,I added my entity again and according to that I recreated models for the associated tables removing the earlier ones.
It solved my problem finally .
I found this link Entity Framework 5 Invalid Column Name error related to somewhat similar problem.
Here also similar kind of error happened after the date time field. Check if your datetime field PurchaseOrderDate is nullable.
Many tools exist that can convert your sql queries to linq, in case you don't wanna write it urself. Try the following sites, works well in my case:
http://www.sqltolinq.com/
http://www.linqpad.net/

C# MySQL joins 3 tables

I am currently using C# and Mysql (XAMPP). I have 3 tables as shown below:
tblILearnQuestion : IlearnQuestionId, Question
tblILearnAnswer : ILearnAnswerId, ILearnQuestionId, StudentId, dateSubmited
tblILearnMarks : ILearnMarkId, ILearnAnswerId, Comments, mark
I need a single query to get the following data : question, studentid , mark and comment. I have tried this but it does not work:
SELECT * FROM tblIlearnQuestion
INNER JOIN tblilearnanswer ON
tblilearnquestion.ilearnquestionid = tblilearnanswer.ilearnquestionid
INNER JOIN ilearnmarks ON
tblilearnanswer.ilearnanswerid = tblilearnmarks.ilearnanswerid
It says some columns does not exist and I have checked, I did name the columns correctly as it is in my database.
It looks like you have wrong name for the table in the second join. You wrote that your table name is tblILearnMarks but you used ilearnmarks in the query. As you can see tbl prefix is missing.
Your syntax is just a bit off with the joins. This should straighten things up:
select *
from tblIlearnQuestion
inner join tblilearnanswer on tblilearnquestion.ilearnquestionid = tblilearnanswer.ilearnquestionid
inner join tblilearnmarks on tblilearnmarks.ilearnanswerid = tblilearnanswer.ilearnanswerid

How do I use multiple IDs from a table with an INNER JOIN using SQL?

I have a list of SiteUsers in one table and another table has columns with different types of owners (ID) for the record. For example, the SiteUserID in the SiteUsers table will be used for the SalesRepID, the StaffingManagerID, and RecruiterID in the Fill table. Of course, the SiteUserID is different for each of the values in the Fill table.
I'd like to return the name of the SiteUser for each ID column in the Fill Table.
How do I properly construct a JOIN statement to do this?
I'm guessing this is done through INNER JOIN, but I'm not sure.
My current select statement already has an INNER JOIN as I'm pulling the name of the FillType from another table. I'm using this in an asp.net application.
I'm not sure if this is even possible. Any help is appreciated.
Since each of the IDs in the Fills table allows null, you probably want to LEFT JOIN to the SiteUsers table like so:
SELECT f.FillID, s1.SiteUserLastName 'SalesRep', s2.SiteUserLastName 'StaffingManager', s3.SiteUserLastName 'Recruiter'
FROM Fills f
LEFT JOIN SiteUsers s1 on f.SalesRepID = s1.SiteUserID
LEFT JOIN SiteUsers s2 on f.StaffingManagerID = s2.SiteUserID
LEFT JOIN SiteUsers s3 on f.RecruiterID = s3.SiteUserID
You can always UNPIVOT the results like so:
SELECT
DISTINCT
unpvt.FillID
,unpvt.RepID
,unpvt.RepType
,s.SiteUserFirstName
,s.SiteUserLastName
FROM
(SELECT
FillID
,SalesRepID
,StaffingManagerID
,RecruiterID
FROM Fills
) f
UNPIVOT
(RepID FOR RepType IN
(SalesRepID, StaffingManagerID,RecruiterID)
) AS unpvt
JOIN SiteUsers AS s on unpvt.RepID = s.SiteUserID`
Obviously you can play with exact output (such as substituting the RepType for a different value with a CASE statement or whatnot.
My question is: why the piss-poor design? Instead of having three IDs in the Fills table, you should have a junction table between SiteUsers and Fills to allow many-to-many relationships. IF it were designed with a junction table, you'd never have had to ask this question.
You will have to join the Fill table with the SiteUsers table multiple times, one for each xxxID column in the Fills for which you want the SiteUser name and combine the results using an union as below:
select a.SiteUserId, a.SiteUserFirstName, a.SiteUserLastName
from dbo.SiteUsers a
inner join dbo.Fills b on b.SalesRepId = a.SiteUserId
UNION
select a.SiteUserId, a.SiteUserFirstName, a.SiteUserLastName
from dbo.SiteUsers a
inner join dbo.Fills b on b.StaffingManagerId = a.SiteUserId
UNION
select a.SiteUserId, a.SiteUserFirstName, a.SiteUserLastName
from dbo.SiteUsers a
inner join dbo.Fills b on b.RecruiterId = a.SiteUserId

Pulling out different columns from different tables using LINQ

I have two tables:
Entity
ID (PK), int
Name
Descrip
Users
ID (PK)
EntityID, int (this is not connected to Entity table)
Now I am using LINQ to pull the records which has a Entity.ID = something. Which will show me couple of records in my GridView.
Here is my LINQ statement:
protected void Page_Load(object sender, EventArgs e)
{
string getEntity = Request.QueryString["EntityID"];
int getIntEntity = Int32.Parse(getEntity);
OISEntityTestingDataContext db = new OISEntityTestingDataContext();
//OISLinqtoSQLDataContext db = new OISLinqtoSQLDataContext();
var tr =
from r in db.Users
join s in db.Entities on r.UserID equals s.ID
where s.ID == getIntEntity
select new
{
//To Show Items in GridView!
};
GridView1.DataSource = tr;
GridView1.DataBind();
}
Now here I am getting an error mesg on 'join':
The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.
What does that mean? Can someone please help me on this. Thank you!
Basically the error you receive tells you that the compiler does not know a way to compare the two values because one is different from the another. Are you sure that you are not comparing a string to an int? If this is your case you can obviously parse the string as shown below:
var tr =
from r in db.Users
join s in db.Entities on int.Parse(r.UserID) equals s.ID
where s.ID == getIntEntity
select new
{
//To Show Items in GridView!
};
I'd wager that the type of one of your join conditions doesn't match the type of the other.
The type of one of the expressions in the join clause is incorrect.
Make sure they match in your entity mappings.
In your post you list your tables as having a column "ID" but in the join one is ID and the other is UserID. Are you sure your joining on the correct column?

Categories