Find missing items in a List<T> - c#

Can someone convert this to C# LINQ for me please ??
SELECT *
FROM vf
LEFT JOIN dbvf
ON vf.sid =dbvf.sid
AND vf.cid =dbvf.cid
WHERE dbvf.sid IS NULL
Both vf and dbvf are List<T>. sid and cid are integers.
What I am trying to do is find items in vf that are missing in dbvf.

try this
var ret = from p1 in vf
join p2 in dbvf
on p1.sid equals p2.sid && p1.cid equals p2.cid into g
from p2 in g.DefaultIfEmpty()
where p2 == null
select new {vf=p1, dbvf=p2}
or this simple
vf.Except(dbvf);

something like below
from dbvf in dbvfs
from vf in vfs
where vf.sid == dbvf.sid && vf.cid == dbvf.cid
where dbvf.sid == null
select new { dbvf = dbvf, vf = vf}

Try something like this:
var query =
from v in vf
join d in dbvf
on new { v.sid, v.cid }
equals new { d.sid, d.cid } into gj
where !gj.Any()
select v;
As stated earlier, your purpose is to do an "except". I've answered how to do this with left-join semantics.
var query =
from v in vf
join d in dbvf
on new { v.sid, v.cid }
equals new { d.sid, d.cid } into gj
from d in gj.DefaultIfEmpty()
where d == null
select v;
The anonymous types used here appear to be black magic to the uninitiated. However, the compiler creates the anonymous types (actually it's just one type) with exactly two properties named sid and cid as well as providing implementations for Equals and GetHashCode that Join will use in its implementation. My choice of gj for the into clause is because introducing the into causes the compiler to do a GroupJoin instead of a regular Join call.
I can add to the query to get a similar feel to your SQL sample by adding a from d in gj.DefaultIfEmpty() clause that reinstates the d range variable previously hidden by the into clause. Now I can add the where d == null clause nearly reaching parity with the original SQL.
This anonymous type introduction is something you may need to use again if you ever want to do other operations such as group by both sid and cid.

Related

Syntax to SubSelect in a Linq Select

I have a syntax problem and need some smart folks than me.
Here is my select statement
var Materials = from j in db.Jobs
join je in db.a_Job_Extensions on j.Top_Lvl_Job equals je.Job
join mr in db.Material_Reqs on j.Job1 equals mr.Job
join m in db.Materials on mr.Material equals m.Material1
where jobList.Contains(j.Top_Lvl_Job)
select new
{
je.PCR,
mr.Job,
j.Top_Lvl_Job,
OrderQty = ((from j1 in db.Jobs where j1.Job1 == j.Top_Lvl_Job select new { j1.Order_Quantity}).FirstOrDefault()).ToString(),
j.Part_Number,
mr.Material,
mr.Description,
mr.Est_Qty,
m.Status,
theClass = m.Class == null? "": m.Class
};
The j1.Order_Quantity is a double in the Job table. But when I run the query, it returns a value of "{ Order_Quantity = 607 }".
My desire is to have it return just the value of "607".
What am I doing wrong here?
The code was originally trying to bring it out as a double, but I switch to string to see what was coming out. I'm coming from a sql background so I must be missing something silly.
Try this
((from j1 in db.Jobs where j1.Job1 == j.Top_Lvl_Job select
j1.Order_Quantity.ToString()).FirstOrDefault())

Unable to cast anonymous list into known list in LINQ

I have a LINQ Query which returns me results from one table. I need to convert it into the List of that table model. The anonymous type of groupManager is List<a> wherea is {Group g5}
var groups = new List<Group>();
var groupManager = (from a in db.AUsers
join b in db.BUsers on a.Id equals b.UserID into group1
from g1 in group1.DefaultIfEmpty()
join c in db.UserRoles on g1.ID equals c.UserID into group2
from g2 in group2.DefaultIfEmpty()
join d in db.Roles on g2.RoleID equals d.ID into group3
from g3 in group3.DefaultIfEmpty()
join e in db.RoleGroups on g3.ID equals e.RoleID into group4
from g4 in group4.DefaultIfEmpty()
join f in db.Groups on g4.GroupID equals f.ID into group5
from g5 in group5.DefaultIfEmpty()
where a.Id == user.ID && g5.Name != ""
select new{ Group = g5}).ToList();
groups = groupManager.Cast<Group>().ToList();
This code does not seem to work.The error I am getting is {"Unable to cast object of type '<>f__AnonymousType11`1[Group]' to type 'Group'."} Am I missing something?
hmmm... did you try this?
select new Group(g5)).ToList();
or this
select g5).ToList();
hard to say more without knowing anything about the group object or the other types in your example.
You can likely do this without the anonymous type or the cast.
var groups = (from a in db.AUsers
// Your query...
select new Group
{
// Properties of Group
Name = g5.Name,
AnotherProperty = g5.AnotherProperty
}).ToList();
Provided answers were absolutely correct, but I guess it could be good to point one subtle thing out regarding Cast method (and to answer "Am I missing something" part).
Cast method really serves different purpose than casting all objects in list to another type. No surprise that compiler throws this exception since what Cast does is taking IEnumerable (non generic version) and returning the same collection, but with generic IEnumerable<T>. This is one of two methods in LINQ that are taking non generic IEnumerable as an argument (the second is OfType), so you could have a collection of given type, cast it to IEnumerable<T> and use other LINQ methods which require IEnumerable<T> as an argument.
Just look at the source code
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source) {
IEnumerable<TResult> typedSource = source as IEnumerable<TResult>;
if (typedSource != null) return typedSource;
if (source == null) throw Error.ArgumentNull("source");
return CastIterator<TResult>(source);
}
and in CastIterator
foreach (object obj in source) yield return (TResult)obj;
so your collection should be able to be casted to given type T in order to Cast to work. It won't cast your anonymous types to concrete types.
If you select the actual object then that's what you get back as an IEnumerable of Group:
var groups = new List<Group>();
var groupManager = (from a in db.AUsers
join b in db.BUsers on a.Id equals b.UserID into group1
from g1 in group1.DefaultIfEmpty()
join c in db.UserRoles on g1.ID equals c.UserID into group2
from g2 in group2.DefaultIfEmpty()
join d in db.Roles on g2.RoleID equals d.ID into group3
from g3 in group3.DefaultIfEmpty()
join e in db.RoleGroups on g3.ID equals e.RoleID into group4
from g4 in group4.DefaultIfEmpty()
join f in db.Groups on g4.GroupID equals f.ID into group5
from g5 in group5.DefaultIfEmpty()
where a.Id == user.ID && g5.Name != ""
select g5).ToList()
groups = groupManager;
The .ToList() will then convert it to a list. No need to create a dynamic object and then cast.

Differences between two linq query result

I want to learn why these two queries return different results.
This query returns 6:
var a = (from belg in contextArchive.Belgeler
join zrf in contextArchive.Zarflar on belg.Parent_ID equals zrf.ID
where belg.RefETTN == this.BelgeETTN
select new { zrf }).Count();
While this query returns 3:
var b = (from belg in contextArchive.Belgeler
join zrf in contextArchive.Zarflar on belg.Parent_ID equals zrf.ID
where belg.RefETTN == this.BelgeETTN
select new { zrf }).ToList();
countKabulRed = b.Count();
I believe there are some null values in b. The different between a and b is that a uses SQL's COUNT that neglects null values, while b's Count() includes both null and non-null values.

linq - how combine conditions in a join statement

im working with xml and linq.
I have 2 xml files both contain "ID" and "LANGUAGE"
I want to do a join based on where the both the ID and LANGUAGE are equal in both files
I have something like this:
var data=
from details in h_details.Descendants("ROW")
join inst in instance.XPathSelectElements("//Row")
on details.Element("ID").Value
equals inst.XPathSelectElement("Field[#Name=\'h_id\']").Value
and on details.Element("LANGUAGE").Value
equals inst.XPathSelectElement("Field[#Name=\'h_lang\']").Value
basically the "and" statement wont work, so how do i join based on 2 conditions?
Anonymous types to the rescue.
var data=
from details in h_details.Descendants("ROW")
join inst in instance.XPathSelectElements("//Row")
on new {
x = details.Element("ID").Value,
y = details.Element("LANGUAGE").Value
} equals new {
x = inst.XPathSelectElement("Field[#Name=\'h_id\']").Value,
y = inst.XPathSelectElement("Field[#Name=\'h_lang\']").Value
}
select ... ;
try union to get the both lists and join them

What is the syntax for an inner join in LINQ to SQL?

I'm writing a LINQ to SQL statement, and I'm after the standard syntax for a normal inner join with an ON clause in C#.
How do you represent the following in LINQ to SQL:
select DealerContact.*
from Dealer
inner join DealerContact on Dealer.DealerID = DealerContact.DealerID
It goes something like:
from t1 in db.Table1
join t2 in db.Table2 on t1.field equals t2.field
select new { t1.field2, t2.field3}
It would be nice to have sensible names and fields for your tables for a better example. :)
Update
I think for your query this might be more appropriate:
var dealercontacts = from contact in DealerContact
join dealer in Dealer on contact.DealerId equals dealer.ID
select contact;
Since you are looking for the contacts, not the dealers.
And because I prefer the expression chain syntax, here is how you do it with that:
var dealerContracts = DealerContact.Join(Dealer,
contact => contact.DealerId,
dealer => dealer.DealerId,
(contact, dealer) => contact);
To extend the expression chain syntax answer by Clever Human:
If you wanted to do things (like filter or select) on fields from both tables being joined together -- instead on just one of those two tables -- you could create a new object in the lambda expression of the final parameter to the Join method incorporating both of those tables, for example:
var dealerInfo = DealerContact.Join(Dealer,
dc => dc.DealerId,
d => d.DealerId,
(dc, d) => new { DealerContact = dc, Dealer = d })
.Where(dc_d => dc_d.Dealer.FirstName == "Glenn"
&& dc_d.DealerContact.City == "Chicago")
.Select(dc_d => new {
dc_d.Dealer.DealerID,
dc_d.Dealer.FirstName,
dc_d.Dealer.LastName,
dc_d.DealerContact.City,
dc_d.DealerContact.State });
The interesting part is the lambda expression in line 4 of that example:
(dc, d) => new { DealerContact = dc, Dealer = d }
...where we construct a new anonymous-type object which has as properties the DealerContact and Dealer records, along with all of their fields.
We can then use fields from those records as we filter and select the results, as demonstrated by the remainder of the example, which uses dc_d as a name for the anonymous object we built which has both the DealerContact and Dealer records as its properties.
var results = from c in db.Companies
join cn in db.Countries on c.CountryID equals cn.ID
join ct in db.Cities on c.CityID equals ct.ID
join sect in db.Sectors on c.SectorID equals sect.ID
where (c.CountryID == cn.ID) && (c.CityID == ct.ID) && (c.SectorID == company.SectorID) && (company.SectorID == sect.ID)
select new { country = cn.Name, city = ct.Name, c.ID, c.Name, c.Address1, c.Address2, c.Address3, c.CountryID, c.CityID, c.Region, c.PostCode, c.Telephone, c.Website, c.SectorID, Status = (ContactStatus)c.StatusID, sector = sect.Name };
return results.ToList();
You create a foreign key, and LINQ-to-SQL creates navigation properties for you. Each Dealer will then have a collection of DealerContacts which you can select, filter, and manipulate.
from contact in dealer.DealerContacts select contact
or
context.Dealers.Select(d => d.DealerContacts)
If you're not using navigation properties, you're missing out one of the main benefits on LINQ-to-SQL - the part that maps the object graph.
Use Linq Join operator:
var q = from d in Dealer
join dc in DealerConact on d.DealerID equals dc.DealerID
select dc;
basically LINQ join operator provides no benefit for SQL. I.e. the following query
var r = from dealer in db.Dealers
from contact in db.DealerContact
where dealer.DealerID == contact.DealerID
select dealerContact;
will result in INNER JOIN in SQL
join is useful for IEnumerable<> because it is more efficient:
from contact in db.DealerContact
clause would be re-executed for every dealer
But for IQueryable<> it is not the case. Also join is less flexible.
Actually, often it is better not to join, in linq that is. When there are navigation properties a very succinct way to write your linq statement is:
from dealer in db.Dealers
from contact in dealer.DealerContacts
select new { whatever you need from dealer or contact }
It translates to a where clause:
SELECT <columns>
FROM Dealer, DealerContact
WHERE Dealer.DealerID = DealerContact.DealerID
Inner join two tables in linq C#
var result = from q1 in table1
join q2 in table2
on q1.Customer_Id equals q2.Customer_Id
select new { q1.Name, q1.Mobile, q2.Purchase, q2.Dates }
Use LINQ joins to perform Inner Join.
var employeeInfo = from emp in db.Employees
join dept in db.Departments
on emp.Eid equals dept.Eid
select new
{
emp.Ename,
dept.Dname,
emp.Elocation
};
Try this :
var data =(from t1 in dataContext.Table1 join
t2 in dataContext.Table2 on
t1.field equals t2.field
orderby t1.Id select t1).ToList();
OperationDataContext odDataContext = new OperationDataContext();
var studentInfo = from student in odDataContext.STUDENTs
join course in odDataContext.COURSEs
on student.course_id equals course.course_id
select new { student.student_name, student.student_city, course.course_name, course.course_desc };
Where student and course tables have primary key and foreign key relationship
try instead this,
var dealer = from d in Dealer
join dc in DealerContact on d.DealerID equals dc.DealerID
select d;
var Data= (from dealer in Dealer join dealercontact in DealerContact on dealer.ID equals dealercontact.DealerID
select new{
dealer.Id,
dealercontact.ContactName
}).ToList();
var data=(from t in db.your tableName(t1)
join s in db.yourothertablename(t2) on t1.fieldname equals t2.feldname
(where condtion)).tolist();
var list = (from u in db.Users join c in db.Customers on u.CustomerId equals c.CustomerId where u.Username == username
select new {u.UserId, u.CustomerId, u.ClientId, u.RoleId, u.Username, u.Email, u.Password, u.Salt, u.Hint1, u.Hint2, u.Hint3, u.Locked, u.Active,c.ProfilePic}).First();
Write table names you want, and initialize the select to get the result of fields.
from d1 in DealerContrac join d2 in DealerContrac on d1.dealearid equals d2.dealerid select new {dealercontract.*}
One Best example
Table Names : TBL_Emp and TBL_Dep
var result = from emp in TBL_Emp join dep in TBL_Dep on emp.id=dep.id
select new
{
emp.Name;
emp.Address
dep.Department_Name
}
foreach(char item in result)
{ // to do}

Categories

Resources