How to select same column's name from different table in Linq? - linq

I've 2 tables with same column's name, for example, both table A and table B has column's name "Test". I want to select column Test from both table A and B to entity class. How can I do this?

It sounds like you want the two entities of TableA and TableB merged into a new object. You can use the .Select() extension method to create a new anonymous type, or into a class that you already have defined.
The requirement here is that you've got to find a common attribute between TableA and TableB. Here I assume you've got something like ID to match them together.
Anonymous Type
var mergedTests = from a in db.TableA
join b in db.TableB on a.CommonID equals b.CommonID
select new
{ TestFromA = a.Test, TestFromB = b.Test }
.ToList();
Existing Class
List<MyCustomTests> mergedTests = from a in db.TableA
join b in db.TableB on a.CommonID equals b.CommonID
select new MyCustomTests
{ TestName= a.Test, ShortName= b.Test }
.ToList();

class Program
{
static void Main(string[] args)
{
var A = new Data[] {
new Data { Test = 1, Relation = 1 },
new Data { Test = 2, Relation = 2 },
new Data { Test = 3, Relation = 3 },
new Data { Test = 4, Relation = 4 },
new Data { Test = 5, Relation = 5 },
};
var B = new Data[] {
new Data { Test = 2, Relation = 2 },
new Data { Test = 3, Relation = 3 },
new Data { Test = 5, Relation = 5 },
};
var res = from a in A
join b in B on a.Relation equals b.Relation
select new { TestA = a.Test, TestB = b.Test };
}
}
class Data
{
public int Test;
public int Relation;
}

Related

Linq. Query Sum on dataset

I'm a beginner in linq.
I would like to write this query in linq.
Select SUM(importo), anno From(
Select anno, Importo from[Archivio].[dbo].[AAA]
union
Select anno, importo From[Archivio].[dbo].[BBB]) as prova
group by Anno order by anno.
I wrote this:
DataTable Tab_AAA = DS_AAA.Tables[0];
DataTable Tab_BBB = DS_BBB.Tables[0];
IEnumerable<DataRow> query =
(from A in DS_AAA.AsEnumerable()
select A).Union(from B in DS_BBB.AsEnumerable()
select B)
now I can not enter the sum and the group by.
Thank you all
the objects that you are using must be something like this
public class AnnoImporto
{
private int _anno;
private double _importo;
private string _altro;
public AnnoImporto(int aAnno, double aImp, string aAltro)
{
_anno = aAnno;
_importo = aImp;
_altro = aAltro;
}
public int Anno
{
get { return _anno; }
set { _anno = value; }
}
public double Importo
{
get { return _importo; }
set { _importo = value; }
}
public string Altro
{
get { return _altro; }
set { _altro = value; }
}
}
surely you have the year and the amount, think to "altro" as generic eventual other fields. I built two lists of AnnoImporto objects, but the following code will work even on lists of different object (of course, as I just said, just having year and amount...)
List<AnnoImporto> aaa = new List<AnnoImporto>();
List<AnnoImporto> bbb = new List<AnnoImporto>();
aaa.Add(new AnnoImporto(2015, 10,"blabla"));
aaa.Add(new AnnoImporto(2014, 20, "blabla"));
aaa.Add(new AnnoImporto(2013, 15, "blabla"));
aaa.Add(new AnnoImporto(2012, 5, "blabla"));
aaa.Add(new AnnoImporto(2011, 40, "blabla"));
bbb.Add(new AnnoImporto(2011, 50, "blabla"));
bbb.Add(new AnnoImporto(2013, 20, "blabla"));
bbb.Add(new AnnoImporto(2015, 15, "blabla"));
var aaa_mod = from a in aaa
select new
{
Anno = a.Anno,
Importo = a.Importo
};
var bbb_mod = from b in bbb
select new
{
Anno = b.Anno,
Importo = b.Importo
};
var unione = aaa_mod.Union(bbb_mod);
Console.WriteLine("controlliamo la nuova lista:");
foreach (var p in unione)
{
Console.WriteLine($"{p.Anno}, {p.Importo}");
}
var somme = from p in unione
orderby p.Anno
group p.Importo by p.Anno into q
select new
{
Anno = q.Key,
ImportoTotale = q.Sum()
};
Console.WriteLine("controlliamo le somme:");
foreach (var p in somme)
{
Console.WriteLine($"{p.Anno}, {p.ImportoTotale}");
}
I followed step by step your query: first I selected in aaa and in bbb only the fields you need, I made the union of the results and I checked it. Then I did the group by to calculate sums by year.

Comparing two lists with multiple conditions

I have two different lists of same type. I wanted to compare both lists and need to get the values which are not matched.
List of class:
public class pre
{
public int id {get; set;}
public datetime date {get; set;}
public int sID {get; set;}
}
Two lists :
List<pre> pre1 = new List<pre>();
List<pre> pre2 = new List<pre>();
Query which I wrote to get the unmatched values:
var preResult = pre1.where(p1 => !pre
.any(p2 => p2.id == p1.id && p2.date == p1.date && p2.sID == p1sID));
But the result is wrong here. I am getting all the values in pre1.
Here is solution :
class Program
{
static void Main(string[] args)
{
var pre1 = new List<pre>()
{
new pre {id = 1, date =DateTime.Now.Date, sID=1 },
new pre {id = 7, date = DateTime.Now.Date, sID = 2 },
new pre {id = 9, date = DateTime.Now.Date, sID = 3 },
new pre {id = 13, date = DateTime.Now.Date, sID = 4 },
// ... etc ...
};
var pre2 = new List<pre>()
{
new pre {id = 1, date =DateTime.Now.Date, sID=1 },
// ... etc ...
};
var preResult = pre1.Where(p1 => !pre2.Any(p2 => p2.id == p1.id && p2.date == p1.date && p2.sID == p1.sID)).ToList();
Console.ReadKey();
}
}
Note:Property date contain the date and the time part will be 00:00:00.
I fixed some typos and tested your code with sensible values, and your code would correctly select unmatched records. As prabhakaran S's answer mentions, perhaps your date values include time components that differ. You will need to check your data and decide how to proceed.
However, a better way to select unmatched records from one list compared against another would be to utilize a left join technique common to working with relational databases, which you can also do in Linq against in-memory collections. It will scale better as the sizes of your inputs grow.
var preResult = from p1 in pre1
join p2 in pre2
on new { p1.id, p1.date, p1.sID }
equals new { p2.id, p2.date, p2.sID } into grp
from item in grp.DefaultIfEmpty()
where item == null
select p1;

How to iterate through GroupBy groups using Dynamic LINQ? [duplicate]

I am using Dynamic Linq helper for grouping data. My code is as follows :
Employee[] empList = new Employee[6];
empList[0] = new Employee() { Name = "CA", State = "A", Department = "xyz" };
empList[1] = new Employee() { Name = "ZP", State = "B", Department = "xyz" };
empList[2] = new Employee() { Name = "AC", State = "B", Department = "xyz" };
empList[3] = new Employee() { Name = "AA", State = "A", Department = "xyz" };
empList[4] = new Employee() { Name = "A2", State = "A", Department = "pqr" };
empList[5] = new Employee() { Name = "BA", State = "B", Department = "pqr" };
var empqueryable = empList.AsQueryable();
var dynamiclinqquery = DynamicQueryable.GroupBy(empqueryable, "new (State, Department)", "it");
How can I get back the Key and corresponding list of grouped items i.e IEnumerable of {Key, List} from dynamiclinqquery ?
I solved the problem by defining a selector that projects the Key as well as Employees List.
var eq = empqueryable.GroupBy("new (State, Department)", "it").Select("new(it.Key as Key, it as Employees)");
var keyEmplist = (from dynamic dat in eq select dat).ToList();
foreach (var group in keyEmplist)
{
var key = group.Key;
var elist = group.Employees;
foreach (var emp in elist)
{
}
}
The GroupBy method should still return something that implements IEnumerable<IGrouping<TKey, TElement>>.
While you might not be able to actually cast it (I'm assuming it's dynamic), you can certainly still make calls on it, like so:
foreach (var group in dynamiclinqquery)
{
// Print out the key.
Console.WriteLine("Key: {0}", group.Key);
// Write the items.
foreach (var item in group)
{
Console.WriteLine("Item: {0}", item);
}
}

LINQ - How to read ID which is Autonumber after submitting the data

I am working on LINQ. and in one transaction I have to update three different tables.
e.g A(A1,A2,A3) B(B1,B2) AB(A1,B1)
here B1 is autonumber in my database. I want to submit all the changes together. so in one data context I wrote
using (BBBDataContext DC= new BBBDataContext())
{
A tba = new A()
{
A1 = this.A1,
A2 = this.A2,
A3 = this.A3,
};
DC.A.InsertOnSubmit(tba);
B tbb= new B()
{
B2 = this.B2,
};
DC.B.InsertOnSubmit(tbb);
// NOW i WONT B1(WHICH IS AUTONUMBER) FROM B SO THAT I USE IT IN MY NEXT TABLE.
AB tbab = new AB()
{
A1 = this.A1,
B1 = ??????,
};
DC.AB.InsertOnSubmit(tbab);
//FINALLY I WILL WRITE SUBMIT CHANGES SO MY ALL TABLES GET CHANGES SAME TIME
DC.SubmitChanges();
}
Que: what should I write # the place of ?????. for B1 in AB table??
Short answer: B
Bit longer answer:
When you create the object and add it you won't get the ID before you commit. So what you do is reference the object and not the ID property of the object.
class A {
public int Id { get;set;}
public ICollection <B> Bees { get;set;}
}
class B {
public int Id { get;set;}
public int InstanceOfAId { get;set;}
public A InstanceOfA { get;set;}
}
var a = new A();
var b = new B();
b.InstanceOfA = a;
Depending on your model you will define a relationship. In code first you could do it this way:
EntityTypeConfiguration<B> cfgB = new EntityTypeConfiguration<B>();
cfgB.HasRequired(p => p.InstanceOfA).WithMany(p => p.Bees)
.HasForeignKey(p => p.InstanceOfAId);
In EDMX you can do the same in the designer.
You will use InstanceOfA to assign to when inserting, after that InstanceOfAId will always hold the Id value. When retrieving data InstanceOfA will only be filled when requested.
You can use it like this:
var x = DC.B.Include(p=>p.A);
or
var x = DC.B.Select(p=> new { Id = p.Id, A_Id = p.A.Id});
or
var x = DC.A.Select(p=> new { Id = p.Id, BeeCount = p.Bees.Count()});

LINQ - Grouping objects with count of type

I have a collection of objects that each defined by a particular "group". How can I write a LINQ query to produce a count of each object grouped by "group".
As an example, lets say I have the following classes;
public class Release
{
int ReleaseNumber;
public ReleaseDetails[] details;
}
public class ReleaseDetails
{
string Group;
// other details omitted
}
For a given release, I'd like to be able to produce output like;
Release number 1 contains the following details;
- 17 records in Group A
- 12 records in Group B
- 6 records in Group C
Any help is much appreciated.
You can do something like
var q = from d in r.Details
group d by d.Group into counts
select new { Count = counts.Count(), Group = counts.Key };
Full example:
Release r = new Release
{
ReleaseNumber = 1
,
Details = new ReleaseDetails[]
{
new ReleaseDetails { Group = "a"},
new ReleaseDetails { Group = "a"},
new ReleaseDetails { Group = "b"},
new ReleaseDetails { Group = "c"},
new ReleaseDetails { Group = "d"},
new ReleaseDetails { Group = "d"},
new ReleaseDetails { Group = "e"},
}
};
var q = from d in r.Details
group d by d.Group into counts
select new { Count = counts.Count(), Group = counts.Key };
foreach (var count in q)
{
Console.WriteLine("Group {0}: {1}", count.Group, count.Count);
}
Here you go.
public class ReleaseDetails
{
public string Group { get; set; }
public ReleaseDetails() {}
public ReleaseDetails(string grp){Group = grp;}
}
var qry = new Release();
qry.details = new List<ReleaseDetails>();
qry.details.Add(new ReleaseDetails("A"));
qry.details.Add(new ReleaseDetails("A"));
qry.details.Add(new ReleaseDetails("B"));
qry.details.Add(new ReleaseDetails("C"));
qry.details.Add(new ReleaseDetails("C"));
qry.details.Add(new ReleaseDetails("B"));
var result = from x in qry.details
group x by x.Group into g
select new
{
Count = g.Count(),
Group = g.Key
};
//Or using Labmda
var result1 = qry.details.GroupBy(x => x.Group).Select(g => new { Count = g.Count(), Group = g.Key });

Resources