Can I optimize my LINQ query? [closed] - c#

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
I'm trying to create my very first database queries using LINQ. For practice I'm using the Adventure Works 2014 database from Microsoft.
DB Diagram.
One of my first goals is to create static method for DataService returning a list of all products for given vendor's name. It looks like my method returns the correct data, but I think it is very poorly optimized. Can I improve it somehow?
public static List<Product> GetProductsByVendorName(string vendorName)
{
AdventureWorksDatabaseClassDataContext dc = new AdventureWorksDatabaseClassDataContext();
int vendorID = dc.Vendors.Where(vendor => vendor.Name == vendorName).Select(vendor => vendor.BusinessEntityID).First();
IEnumerable <ProductVendor> productsVendor = dc.ProductVendors;
IEnumerable<int> selectedProductsID = from ProductVendor productVendor in productsVendor
where productVendor.BusinessEntityID == vendorID
select productVendor.ProductID;
IEnumerable<Product> products = dc.Products;
IEnumerable<Product> selectedProducts = from Product p in products
where selectedProductsID.Contains(p.ProductID)
select p;
return selectedProducts.ToList();
}

You should use joins on database side to avoid transferring data over network and loading entities into memory:
from v in dc.Vendors
join pv in dc.ProductVendors on v.BusinessEntityID equals v.BusinessEntityID
join p in dc.Products on p.ProductID equals pv.ProductID
where v.Name == vendorName
select p
Note that if you have proper setup of navigation properties, then this query can look like
dc.Vendors.Where(v => v.Name == vendorName)
.SelectMany(v => v.ProductVendors.Select(pv => pv.Product))

Related

function Return LastOrDefault() [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have ExpesnseIDVM ViewModel that only contains 1 variable ExpenseID to hold the last value from the database
public IEnumerable<ExpesnseIDVM> Profile(LoginVM loginVM)
{
var data = (from a in context.Employees
where a.Email == loginVM.Email
join b in context.Expenses on a.EmployeeId equals b.EmployeeId
select new ExpesnseIDVM()
{ ExpenseID = b.ExpenseId }).ToList().LastOrDefault();
return data;
}
I have a problem with the return type, what type of return type should I use to get the values
Four problems here:
SQL Server do not guarantee order of the items if you do not specify OrderBy
SQL do not have LastOrDefault direct translation. EF may try to reverse defined OrderBy and call FirstOrDefault - again OrderBy required
LastOrDefault returns one instance, not enumerable
ToList() loads whole table into the memory, but you need just one record, so do not use it.
Consider to rewrite your query in the following way:
public ExpesnseIDVM Profile(LoginVM loginVM)
{
var data = (from a in context.Employees
where a.Email == loginVM.Email
join b in context.Expenses on a.EmployeeId equals b.EmployeeId
orderby b.ExpenseId descending
select new ExpesnseIDVM()
{ ExpenseID = b.ExpenseId }).FirstOrDefault();
return data;
}
You have IQueryable?<T> as return value of the linq query, then you have .ToList() That makes EF to calculate the query, getting List<T> and finally .LastOrDefault() that returns single object of T.

Inner Join LINQ Without making a New Model [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I'm working with LINQ and I need to do a inner join. This is my code:
var requests =
(from request in db.Request
join estatus in db.typesStatus
on request.fkStatus equals estatus.idStatus
where request.fkStatus == status && DbFunctions.TruncateTime(request.dateRquest) == DbFunctions.TruncateTime(fecha)
select new { request = request, estatus = estatus.status, nombre = (String)UserAccessRequest.checkUserAsync(request.wiwMakeRequest, "name").Result })
.ToList();
I'm trying to call a method inside my LINQ query. This one calls an API and returns a string but I recieved the next error:
LINQ to Entities does not recognize the method
'System.Threading.Tasks.Task`1[System.Object]
checkUserAsync(System.String, System.String)' method, and this method
cannot be translated into a store expression.
Is any way to make the LINQ query without making a model to the result of this LINQ query?
Just call your method after LINQ query loaded data into memory:
var requests =
(from request in db.Request
join estatus in db.typesStatus
on request.fkStatus equals estatus.idStatus
where request.fkStatus == status && DbFunctions.TruncateTime(request.dateRquest) == DbFunctions.TruncateTime(fecha)
select new { request = request, estatus = estatus.status })
.ToList()
.Select(i => new { i.request, i.estatus, nombre = (String)UserAccessRequest.checkUserAsync(i.request.wiwMakeRequest, "name").Result })
.ToList()

how to use joining with LinQ To Entity [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have this code
var value = (from dc in _context.ContractDetails
where dc.EmployeeID == id
select dc.Amount);
return value;
}
is it acceptable to do Value.Sum();
You want to return the sum it looks like. Instead of having query be a decimal, just let it be what it wants (var, it's really IEnumerable<decimal>). Then you can return an aggregate on that. Sum for example
var query = from emp in Employees
join cd in ContractDetails
on emp.EmployeeID equals cd.EmployeeID
where cd.EmployeeID == id
select cd.Amount;
return query.Sum();
If this is all it does, then I also feel like you don't need to join at all, and it would be simpler to do
var query = from cd in ContractDetails
where cd.EmployeeID == id
select cd.Amount;
return query.Sum();
... unless you were using the join to test for the existence of an employee in the Employee table as a condition.
Your linq statement results in an IQueryable<Amount>, you would need to take that result and call Sum() on it to get the result you're seeking.
First, isn't there a navigation property you can use (i.e. Employee.ContracteDetails) instead of manually joining the two sets? For example,
var sum = _context.Employee
.Where( e => e.Id == id )
.Select( e => e.ContractDetails.Sum( cd => cd.Amount ) )
.SingleOrDefault();
Second, you're not using any information you need from Employee, even your where clause references ContractDetails alone; why start your query there? Work with _context.ContractDetails instead:
var sum = _context.ContractDetails
.Where( cd => cd.EmployeeId == id )
.Sum( cd => cd.Amount );

how to write a nested Sql query in Linq [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
so i have this query in sql:
select (select ConfigItemDescripcion from SGRC_ConfigItem where ConfigId = 'SEGM' and ConfigItemId = SegmentoId) Segmento,
(select ConfigItemDescripcion from SGRC_ConfigItem where ConfigId = 'MRCA' and ConfigItemId = MarcaId) Marca,
Producto,
Familia
from sgrc_emisor
where EmisorCuenta = '3702406435'
I want to write the same query in a linq expression or a lambda expression.
Thanks for the help in advance
Finally i manage to come up with the query in linq, dont know how to do it in lambda, but it works fine.
var obj = (from emisor in _context.DbSetEmisores
where emisor.EmisorCuenta == cuenta
select new EmisorDto
{
Segmento =
((from itemConf in _context.ItemsDeConfiguracion
where itemConf.ConfigID == "SEGM" && itemConf.ConfigItemID == emisor.SegmentoId
select new { itemConf.ConfigItemDescripcion }).FirstOrDefault().ConfigItemDescripcion),
Marca =
((from itemConf in _context.ItemsDeConfiguracion
where itemConf.ConfigID == "MRCA" && itemConf.ConfigItemID == emisor.MarcaId
select new { itemConf.ConfigItemDescripcion }).FirstOrDefault().ConfigItemDescripcion),
Producto = emisor.Producto,
Familia = emisor.Familia,
SegmentoId = emisor.SegmentoId,
MarcaId = emisor.MarcaId,
}).FirstOrDefault();
When using LINQ you can use either Query syntax as shown in the LINQ below (If you are familiar with SQL then this looks more natural).
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq
The other option is to use Method syntax, and below is a short example. This allows for chaining of methods, biggest thing to keep in mind is "var" should be used, the return type is dynamic and the compiler will help you out a lot if you just use "var"
var items = _list.Where(x => x.Attribute1 == "NextField")
.Where(x => x.Attribute2 == "Something else");
Other things that hangs folks up sometimes is LINQ uses "delayed execution"

Combine two tables using Entity Framework [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have the following query:
{
SELECT A.Id, C1.FullName AS APerson, C2.FullName As BPerson
FROM TableA AS A
LEFT JOIN TableC AS C1 ON A.FK_PersonA = C1.Id
LEFT JOIN TableC AS C2 ON A.FK_PersonB = C2.Id
UNION
SELECT B.Id, B.FullName1 AS APerson, B.FullName2 AS BPerson
FROM TableB AS B
}
I would like to convert this to an Entity Framework lambda query, is this possible?
Data Model
Firstly you should create repositories for your models. Read about this here.
So , you can use this:
var ret =
(from taRec in TableA.GetAll()
join tc1 in TableC.GetAll on taRec.FK_PersonA equals tc1.Id
into tcRecs1
from tcRec1 in tcRecs1.DefaultIfEmpty()
join tc2 in TableC.GetAll on taRec.FK_PersonB equals tc2.Id
into tcRecs2
from tcRec2 in tcRecs2.DefaultIfEmpty()
select new {
taRec.Id, APerson = tcRec1.FullName, BPerson = tcRec2.FullName
}).Union(
from tbRec in TableB.GetAll()
select new {
tbRec.Id, APerson = tbRec.FullName, BPerson = tbRec.FullName
});

Categories

Resources