I am new to LINQ queries, please help me out to find the solution.
I have a source in Entity Framework data model, there is a table currency bound to the source with columns currencyID and CurrencyName.
I need to get the values from the database to the DataTable using a LINQ query.
I tried something like mentioned below but it's not working:
var dataset = Source.T_Currency
.Where(x=> x.CurrencyID == x.CurrencyID && x.CurrencySymbol == x.CurrencySymbol)
.Select(x => new x.Currency
{
CurrencyID = x.CurrencyID,
CurrencySymbol = x.CurrencySymbol
}).ToList();
If you want to select all rows from T_Currency then try
Source.T_Currency
.Select(x => new
{
x.CurrencyID,
x.CurrencySymbol
})
.ToList()
To filter result by any value add Where statement before Select:
Source.T_Currency
.Where(x => x.CurrencySymbol == myCurrency) // where myCurrency is variable/parameter
.Select(x => new
{
x.CurrencyID,
x.CurrencySymbol
})
.ToList()
It is example with Select statement but actually in this case it is not requied, so Source.T_Currency.ToLost() returns the same result as the first code snippet. Difference is in type of values but if you can use original class then you should not create anonimous type.
you should use LINQ Join like this example:
var custSupJoin =
from sup in suppliers
join cust in customers on sup.Country equals cust.Country
select new { Country = sup.Country, SupplierName = sup.SupplierName, CustomerName = cust.CompanyName };
Related
For the given data set, I want to return the unique rows for each OrderId that has the lowest number for Status, so the result would be:
I have a working query that does that:
var result = _dbContext.Orders
.GroupBy(s => s.OrderId)
.Select(group => group.OrderBy(x => x.Status).First()).ToList();
However, I would like to modify this query to only return three selected fields for each table row, rather than the dozens that exist. I know I need to add something like this:
.Select(group => new
{
OrderId = ???,
Status = ???,
Date = ???
}
But I am unable to add this to my existing query and have it still work. How can I do this?
You can try to do something like this:
var result = _dbContext.Orders
.GroupBy(s => s.OrderId)
.Select(group => group.OrderBy(x => x.Status).First())
.Select(order => new
{
OrderId = order.OrderId,
Status = order.Status,
Date = order.Date
})
.ToList();
In SQL you'd use:
SELECT OrderID,MIN(Status) as Status
FROM Orders
GROUP BY OrderID
A LINQ query is similar:
var query = context.Orders
.GroupBy(o=>o.OrderId)
.Select(g=> new {
OrderId=g.Key.OrderId,
Status=g.Min(o=>o.Status)
});
var results=query.ToList();
I want to create a linq to sql query that will return a list of objects with a sublist that has been filtered.
It sounds easy but I'm not sure how to make this to work
Here the SQL Query which returns what I want:
select * from Texts t inner join Translations tt on t.TranslationId = tt.Id
inner join Pages p on tt.Id = p.TranslationId and tt.NeutralText = p.TitleNeutralTextId
where t.LanguageId = 1
Now I have to write this with linq.
What I've done so far is:
var query = this.Queryable() // Page entity
.AsNoTracking()
.Include(x => x.TitleTranslation.Texts);
return (from m in query
from l in m.TitleTranslation.Texts
where m.TitleTranslation.Texts.Any(l => l.LanguageId == 1)
select m);
But it didn't work because I got the sublist with all languages instead of language with id #1 only.
Thanks for helping,
David
Any specific reason you are writing query? Either you can use Eager Loading of EF to load all the child tables, Or below Linq statement can fetch the required result
var result = texts.Join(translations, t => t.TranslationId, tt => tt.Id, (t, tt) => new {t, tt})
.Join(pages, ttt => new { Id = ttt.tt.Id, NeutralTextId = ttt.tt.NeutralText }, p => new { Id = p.TranslationId, NeutralTextId = p.TitleNeutralTextId }, (ttt, p) => new {ttt, p})
.Where(tttt => tttt.ttt.t.LanguageId == 1);
Here replace texts, translations and pages with actual dbContext entities collection property.
I think you must try lime this. this will work for you .
This will be similar to sql query
One way to do this .
var result = from m in Texts
join Translations on Texts.TranslationId = Translation.Id
Join Pages on Translations.NeutralText = Pages.NeutralText
where Texts.LanguageId = 1
select m
There an other way to do this using entity framework
var result =
this.Queryable().AsNoTracking().Include(x=>x.Translations).Where(x=>x.LanguageId= 1)
I found the solution I wanted thanks to Hasnain Bukhari.
The solution was to start from the text table, assign the filter, include the desired Entity (Page) and put the results into memory (ToList()). Then select pages. It will give the result I want in the order I have to.
var query = textService.Queryable()
.AsNoTracking()
.Include(x => x.Translation.Pages)
.Where(x => x.LanguageId == languageId).ToList();
return query.SelectMany(x => x.Translation.Pages);
I need to select only two columns from Hospital table, HospitalId and Name.
i tried the below code it selects all columns from Hospital table which lead to slow performance. Please help me to select only two columns from Hospital table
public HttpResponseMessage GetAvailableHospitalsByAjax(System.Guid? DirectorateOfHealthID = null, System.Guid? UnitTypeID = null, string DeviceTypeIDs = null)
{
Context db = new Context();
var query = db.Hospitals.AsQueryable();
if (UnitTypeID != null)
{
query = query.Where(j => j.HospitalDepartments.Any(www => www.Units.Any(u => u.UnitTypeID == UnitTypeID)));
}
if (DirectorateOfHealthID != null)
{
query = query.Where(h => h.DirectorateHealthID == DirectorateOfHealthID);
}
query = query.Where(j => j.HospitalDepartments.Any(u => u.Units.Any(d => d.Devices.Any(s => s.Status == Enums.DeviceStatus.Free)))
&& j.HospitalDepartments.Any(hd => hd.Units.Any(u => u.Beds.Any(b => b.Status == Enums.BedStatus.Free))));
var list = query.ToList().Select(w => new HospitalInfo()
{
Id = w.ID,
Name = w.Name
}).ToList();
return Request.CreateResponse(HttpStatusCode.OK, list);
}
IQueryable<T> executes select query on server side with all filters. Hence does less work and becomes fast.
IEnumerable<T> executes select query on server side, load data in-memory on client side and then filter data. Hence does more work and becomes slow.
List<T> is just an output format, and while it implements IEnumerable<T>, is not directly related to querying.
So,
var list = query.ToList().Select(w => new HospitalInfo()
{
Id = w.ID,
Name = w.Name
}).ToList();
In your code you use query.ToList(). This means at first it pull all data into memory then apply Select query.If you want to retrieve HospitalID and Name then remove ToList() then your code like
var list = query.Select(w => new HospitalInfo
{
Id = w.ID,
Name = w.Name
}).ToList();
Remove the ToList call before the projection:
var list = query.Select(w => new HospitalInfo()
{
Id = w.ID,
Name = w.Name
}).ToList();
With that ToList call you are materializing your query before do the projection
Because you do query.ToList() this materialises the entire query with all columns into memory. It's actually a bad habit to get into. Instead, remove that, you already have it at the end anyway. The Select projection you have will only retrieve the relevant columns though:
var list = query.Select(w => new HospitalInfo()
{
Id = w.ID,
Name = w.Name
}).ToList();
I have a SQL Query to extract sorted data by sum of a column value. I have a table named CustomerPoint and It has 2 columns named CusTomerID and Point , I want to extract the person with the highest SUM of points. Here is my SQL Query and it runs properly. But I need to execute it in EF6.3 with LambdaExpressions or Linq queries.
SELECT SUM(Point) AS POINTS, CustomerID FROM CustomerPoint AS POINTS GROUP BY CustomerID ORDER BY POINTS
Thank you for your help!
Something like this:
from p in context.Points
group p by p.CustomerID into gr
select new { CustomerID = gr.Key, POINTS = gr.Sum(c=>c.Point) } into re
orderby re.POINTS
Please try this.
from cp in db.CustomerPoints
Group cp by cp.CusTomerID into cpg
select new { CusTomerID = cpg.Key, Points = cpg.Sum(c => c.Point)}
orderby cpg.Points
And lambda form for diversity:
var query = youContext.CustomerPoints
.GroupBy(x => x.CustomerID)
.Select(x => new { Points = x.Sum(y => y.Point),
CustomerID = x.Key })
.OrderBy(x => x.Points);
i have 4 table in SQL: DocumentType,ClearanceDocument,Request, RequestDocument.
i want when page load and user select one request, show all Document Based on clearanceType in RequestTable and check in RequestDocument and when exist set is_exist=true
I have written this query with SqlServer Query Editor for get result this Scenario but i can't convert this Query to Linq
select *,
is_Orginal=
(select is_orginal from CLEARANCE_REQUEST_DOCUMENT
where
DOCUMENT_ID=a.DOCUMENT_ID and REQUEST_ID=3)
from
DOCUMENT_TYPES a
where
DOCUMENT_ID in
(select DOCUMENT_ID from CLEARANCE_DOCUMENTS dt
where
dt.CLEARANCE_ID=
(SELECT R.CLEARANCE_TYPE FROM CLEARANCE_REQUEST R
WHERE
R.REQUEST_ID=3))
i write this Query in linq but not work
var list = (from r in context.CLEARANCE_REQUEST
where r.REQUEST_ID == 3
join cd in context.CLEARANCE_DOCUMENTS on r.CLEARANCE_TYPE equals cd.CLEARANCE_ID
join dt in context.DOCUMENT_TYPES on cd.DOCUMENT_ID equals dt.DOCUMENT_ID into outer
from t in outer.DefaultIfEmpty()
select new
{
r.REQUEST_ID,
cd.CLEARANCE_ID,
t.DOCUMENT_ID,
t.DOCUMENT_NAME,
is_set=(from b in context.CLEARANCE_REQUEST_DOCUMENT where
b.REQUEST_ID==r.REQUEST_ID && b.DOCUMENT_ID==t.DOCUMENT_ID
select new{b.IS_ORGINAL})
}
).ToList();
I want convert this Query to LINQ. Please help me. Thanks.
There is no need to manually join objects returned from an Entity Framework context.
See Why use LINQ Join on a simple one-many relationship?
If you use the framework as intended your job will be much easier.
var result = var clearanceTypes = context.CLEARANCE_REQUEST
.Single(r => r.REQUEST_ID == 3)
.CLEARANCE_DOCUMENTS
.SelectMany(dt => dt.DOCUMENT_TYPES)
.Select(a => new
{
DocumentType = a,
IsOriginal = a.CLEARANCE_REQUEST_DOCUMENT.is_original
});
Since your query won't be executed untill you iterate over the data, you can split your query in several subqueries to help you obtain the results like this:
var clearanceIds = context.CLEARANCE_REQUEST
.Where(r => r.REQUEST_ID == 3)
.Select(r => r.CLEARANCE_TYPE);
var documentIds = context.CLEARANCE_DOCUMENTS
.Where(dt => clearanceIds.Contains(dt.CLEARANCE_ID))
.Select(dt => dt.DOCUMENT_ID);
var result = context.DOCUMENT_TYPES
.Where(a => documentIds.Contains(a.DOCUMENT_ID))
.Select(a => new
{
// Populate properties here
IsOriginal = context.CLEARANCE_REQUEST_DOCUMENT
.Single(item => item.DOCUMENT_ID == a.DOCUMENT_ID &&
item.REQUEST_ID == 3)
.IS_ORIGINAL
})
.ToList();