How to extract results from a Linq query? - c#

class Program
{
static void Main(string[] args)
{
MyDatabaseEntities entities = new MyDatabaseEntities();
var result = from c in entities.Categories
join p in entities.Products on c.ID equals p.IDCategory
group p by c.Name into g
select new
{
Name = g.Key,
Count = g.Count()
};
Console.WriteLine(result.ToString());
Console.ReadLine();
}
}
How can I extract the values from ths result set so I can work with them?

foreach (var item in result)
{
var name = item.Name;
var count = item.Count;
...
}
This will only work inside the same method where the LINQ query is located, since the compiler will only then know which properties are available in the anonymous object type (new { }) used in your LINQ select.
If you return a LINQ query to a calling method, and you want to access it in the way shown above, you'd have to define an explicit type and use it in your LINQ query:
class NameCountType
{
public string Name { get; set; }
public int Count { get; set; }
}
...
return from ... in ...
...
select new NameCountType
{
Name = ...,
Count = ...,
};

For example:
foreach (var x in result)
{
Console.WriteLine(x.c.Name);
}

var results = (from myRow in ds.Tables[0].AsEnumerable()
where myRow.Field<String>("UserName") == "XXX"
select myRow).Distinct();
foreach (DataRow dr in results)
UserList += " , "+dr[0].ToString();

Related

The name "covid" doesn't exist in the current context

Hi i convert sql query to linq i got this error. when i remove group by there isn't exception but i should use group by. why i got this exception ?
public List<BiontechSinovacCovidDto> GetBiontechSinovacCovidDto()
{
using(SirketDBContext context=new SirketDBContext())
{
var result =
from asi in context.Asilar
join covid in context.Covids
on asi.CovidId equals covid.CovidId
group asi by asi.AsiIsmi into isim
select new BiontechSinovacCovidDto
{
AsiIsmi=isim.Key,
//exception OrtalamaCovidSuresi=(EF.Functions.DateDiffDay(covid.CovidYakalanmaTarih, covid.CovidBitisTarih)).Average()
};
return result.ToList();
}
}
my sql query
Select
AsiIsmi,
AVG(Cast(DATEDIFF(Day,CovidYakalanmaTarih, CovidBitisTarih)AS FLOAT)) as OrtalamaCovidSuresi
From Asilar
INNER JOIN Covids on Covids.CovidId=Asilar.CovidId
group by AsiIsmi
|AsiIsmi| OrtalamaCovidSuresi|
------- ------------------
Biontech 13.6667
Sinovac 15
BiontechSinovacCovidDto
public class BiontechSinovacCovidDto
{
public string AsiIsmi { get; set; }
public double OrtalamaCovidSuresi { get; set; }
}
Average has overload which accepts lambda. You have to use this version. Also you have to group covid in this case.
public List<BiontechSinovacCovidDto> GetBiontechSinovacCovidDto()
{
using (var context = new SirketDBContext())
{
var result =
from asi in context.Asilar
join covid in context.Covids
on asi.CovidId equals covid.CovidId
group covid by asi.AsiIsmi into isim
select new BiontechSinovacCovidDto
{
AsiIsmi = isim.Key,
OrtalamaCovidSuresi = isim.Average(x => EF.Functions.DateDiffDay(x.CovidYakalanmaTarih, x.CovidBitisTarih))
};
return result.ToList();
}
}

Fill DTO from two distinct objects

I have the following DTO:
public int IdTableOne { get; set; }
public string ValueTableOne { get; set; }
public int IdTableTwo { get; set; }
public string ValueTableTwo { get; set; }
Also, I have two Models (TableOne & TableTwo) and I fill this models in my repository doing the following code:
return dbContext.TableOne;
At this point everything it's okay. TableOne & TableTwo are populated, but now I want to return the combination of these values into my DTO object (TableOneId is equal to TableTwoId, it's a relationship between both tables) for doing this I'm trying something like this:
public IEnumerable<TableOneAndTwoDTO> GetTableOneAndTwo()
{
List<TableOneAndTwoDTO> combination = new List<TableOneAndTwoDto>();
var t1 = myRepository.GetTableOne();
var t2 = myRepository.GetTableTwo();
var query = from p in t1
select new {
IdTableOne = p.Id,
ValueTableOne = p.Value,
};
foreach (var item in query)
{
combination.Add(new TableOneAndTwoDTO { IdTableOne = item.IdTableOne, ValueTableOne = item.ValueTableOne });
}
}
So my question is, how can I add the TableTwo values to my DTO only when IdTableOne = IdTableTwo.
You can join your table results. Something like this:
var query = from p in t1
join j in t2 on p.IdTableOne equals j.IdTableTwo
select new { p, j };
And then you can add the join values to your DTO using something like this:
foreach (var item in query)
{
combination.Add(new TableOnwAndTwoDTO { IdTableOne = item.p.IdTableOne, IdTableTwo = item.j.IdTableTwo... })
}
Just do a LINQ Join. You can avoid a lot of the ceremony from your original code by putting the whole thing into one query and then calling .ToList() before returning.
public IEnumerable<TableOneAndTwoDTO> GetTableOneAndTwo()
{
var t1 = myRepository.GetTableOne();
var t2 = myRepository.GetTableTwo();
var combination =
from p in t1
join j in t2 on p.IdTableOne equals j.IdTableTwo
select new {
IdTableOne = p.Id,
ValueTableOne = p.Value,
IdTableTwo = j.Id,
ValueTableTwo = j.Value,
};
return combination.ToList();
}

SQL query to Linq Lambda Expression - Join same table with group condition

Anyone can help to convert below SQL query to c# LinQ Lambda Expression? Thanks
tbl_CLASS
ClassID Student
Class1 A
Class1 B
Class1 C
Class2 B
Class2 C
Class3 C
Result
Class A B C
Class1 Y Y Y
Class2 N Y Y
Class3 N N Y
SELECT a.ClassID,
A=case when c.ClassID is null then 'N' else 'Y' end,
B=case when B.ClassID is null then'N' else 'Y' end,
C='Y'
FROM tbl_CLASS a
Left join tbl_CLASS b on a.ClassID=b.ClassID AND b.Student='B'
Left join tbl_CLASS c on a.ClassID=c.ClassID AND c.Student='A'
WHERE a.Student='C'
GROUP by a.ClassID,case when c.ClassID is null then 'N' else 'Y' end,case when B.ClassID is null then'N' else 'Y' end
List<Class1> myList = GetClass();
var query = myList
.GroupBy(c => c.ClassID)
.Select(g => new {
ClassID = g.Key,
A = g.Count(c => c.Student=="A")>0?"Y":"N",
B = g.Count(c => c.Student=="B")>0?"Y":"N",
C = g.Count(c => c.Student=="C")>0?"Y":"N"
});
GetClass is get your data
public class Class1
{
public Int32 ClassID {get;set;}
public String A{get;set;}
public String B{get;set;}
public String C{get;set;}
}
When students are dynamic it means you need a result class for result rows like this:
class ResultRow
{
public ResultRow()
{
Students = new Dictionary<string, string>();
}
public string Class { get; set; }
public IDictionary<string, string> Students { get; set; }
}
Because you need dynamic columns for students.
Now I can generate a result similar to your expected result with this code:
var res = tblClass
.GroupBy(g=> g.ClassId)
.Select(c =>
{
var rr = new ResultRow {Class = c.Key};
foreach (var r in tblClass.GroupBy(gg=> gg.Student))
{
rr.Students[r.Key] = "N";
}
foreach (var r in c.Where(w=> w.ClassId == c.Key))
{
rr.Students[r.Student] = "Y";
}
return rr;
})
.toList(); //optional
You can also add these two method to ResultRow class:
public string GetHeader()
{
return Students.Aggregate("Class", (current, s) => current + "|" + s.Key);
}
public string GetSolidRow()
{
return Students.Aggregate(Class, (current, s) => current + "|" + s.Value);
}
[ Demo Here ]
HTH
cannot convert from System.Collections.Generic.List<> to System.Collections.Generic.IEnumerable<>
public SystemAccessList GetAccessList(SystemAccessList systemAccessList)
{
var qresult = db.tbl_SystemAccessList
.GroupBy(g => g.ClassID)
.AsEnumerable().Select(c =>
{
var rr = new ResultRow { Class = c.Key };
foreach (var r in db.tbl_SystemAccessList.GroupBy(gg => gg.StudentID))
{
rr.Student[r.Key] = "N";
}
foreach (var r in c.Where(w => w.ClassID == c.Key))
{
rr.Student[r.StudentID] = "Y";
}
return rr;
}).ToList();
systemAccessList.SystemAccessList.AddRange(qresult);
return systemAccessList;
}

How to get filtered list based on common items in two lists in c#

I am trying to get a list filtered based on the matches of one of the properties with a property of another list.
In below example, only the items which have common 'name' between both lists should be filtered in 1st list. Can some one tell me the most concise way of doing it?
class TCapability
{
public string Name { get; set; }
public int Id { get; set; }
}
class PCapability
{
public string Name { get; set; }
public int Code { get; set; }
}
Input:
var capability = new List<TCapability>()
{
new TCapability() {Name="a", Id=1},
new TCapability() {Name="b", Id=2},
new TCapability() {Name="c", Id=3}
};
var type2Capability = new List<PCapability>()
{
new PCapability() {Name="a", Code=100},
new PCapability() {Name="b", Code=200},
new PCapability() {Name="d", Code=300}
};
Expected Output:
capability =
{
{ Name="a", Id=1 },
{ Name="b", Id=2 }
}
var result = capability.Where(c => type2Capability.Any(c2 => c.Name == c2.Name));
you can try use join clause like this
capability = (from a in capability
join b in type2Capability on a.Name equals b.Name
select a).ToList();
UPDATE on comment if type2Capability can have duplicate names
capability = (from a in capability
join b in type2Capability on a.Name equals b.Name into f
where f.Any()
select a).ToList();
If the lists can get long then a HashSet can speed things up.
var set = new HashSet<string>(type2Capability.Select(t => t.Name));
var res = capability.Where(c => set.Contains(c.Name));

assign value using linq

public class Company
{
public int id { get; set; }
public int Name { get; set; }
}
List<Company> listofCompany = new List<Company>();
this is my collection of company list I want to assign values to Name property using LINQ
listofCompany.Where(d => d.Id = 1);
(I want to assing name property of company id 1)
how do I assign it.?
using Linq would be:
listOfCompany.Where(c=> c.id == 1).FirstOrDefault().Name = "Whatever Name";
UPDATE
This can be simplified to be...
listOfCompany.FirstOrDefault(c=> c.id == 1).Name = "Whatever Name";
UPDATE
For multiple items (condition is met by multiple items):
listOfCompany.Where(c=> c.id == 1).ToList().ForEach(cc => cc.Name = "Whatever Name");
You can create a extension method:
public static IEnumerable<T> Do<T>(this IEnumerable<T> self, Action<T> action) {
foreach(var item in self) {
action(item);
yield return item;
}
}
And then use it in code:
listofCompany.Do(d=>d.Id = 1);
listofCompany.Where(d=>d.Name.Contains("Inc")).Do(d=>d.Id = 1);
It can be done this way as well
foreach (Company company in listofCompany.Where(d => d.Id = 1)).ToList())
{
//do your stuff here
company.Id= 2;
company.Name= "Sample"
}
Be aware that it only updates the first company it found with company id 1. For multiple
(from c in listOfCompany where c.id == 1 select c).First().Name = "Whatever Name";
For Multiple updates
from c in listOfCompany where c.id == 1 select c => {c.Name = "Whatever Name"; return c;}

Categories

Resources