I have two lists rtrn and Zipcodes
rtnr items have a Utility field. I need to return a subset of rtrn where rtrn.Utility exists in field1 or filed2 or field3 of zipocode item
Get the unique utilities from this zipcodes fileds 1-3
DbSet<Utility> utilities;
DbSet<Zipcodes> zipcodes;
var uniqeUtilitiesInZipcodes = zipcodes.Select(x => x.Field1).ToList();
uniqeUtilitiesInZipcodes.AddRange(zipcodes.Select(x => x.Field2).ToList());
uniqeUtilitiesInZipcodes.AddRange(zipcodes.Select(x => x.Field3).ToList());
uniqeUtilitiesInZipcodes = uniqeUtilitiesInZipcodes.Distinct().ToList();
Intersect unique utilities with zipcodes
uniqeUtilitiesInZipcodes = uniqeUtilitiesInZipcodes.Distinct().ToList();
var zipcodesWhereUtilityExistsInAnyUtiltyField = utilities.Intersect(uniqeUtilitiesInZipcodes).ToList();
Related
In my database, I have a table called Employee and it has columns EmpNames and EmpId which same EmpId created User table with user levels. I want to get a list of empNames and id's to who are user level equal to the 4.
This is how I got empname list for a drop down list
List<M_Employee> EmpList = db.CreateEmployee.Where(x => x.Status == true).ToList();
List<SelectListItem> EmpDropDown = EmpList.Select(x => new SelectListItem { Text = x.EmpName, Value = x.Id.ToString() }).ToList();
Same way I have tried to query the user level = 4 and tried to join emp table with user table to get the emp names who assigned user levels to 4 but it didn't work.
Here is my code for that
List<int> TopEmp = db.Master_Users.ToList().Where(r => r.EmpId == int.Parse(db.CreateEmployee.Where(x=> x.Id))).ToList().
Can you help me on this?
Firstly, you need to understand how ToList works.
When you call ToList it means that Entity framework will execute the sql statement constructed at that point and retrieve the results into memory.
You generally want to construct your entire query first and then have that query get all the data you want from the database in the format of an object you want by using .Select(x => x.whatever).ToList(). Otherwise you'll be making multiple calls to the database to get bits of data here and there and then joining them or working with them unnecessarily in memory which is slower than having the database do it.
So your first query where you get the select list items can be rewritten like this:
List<SelectListItem> EmpDropDown = db.CreateEmployee
.Where(x => x.Status == true)
.Select(x => new SelectListItem { Text = x.EmpName, Value = x.Id.ToString() })
.ToList()
And from what you've described you should be able to rewrite the 2nd query like this:
List<int> TopEmp = (from u in db.Master_Users
join e in db.CreateEmployee on u.EmpId equals e.Id
where u.Level == 4
select e.Id
).ToList();
This is using a different query syntax but allows to specify the key to join on easily as I don't know how your foreign keys and navigation properties are setup.
I can't see you dbcontext, maybe it is possible to use include too, but for the start try this
List<SelectListItem> EmpDroDown = (from emp in db.CreateEmployee
join usr in db.Master_Users on emp.Id equals usr.EmpId
where emp.Status == true && usr.UserLevel==4
select new SelectListItem { Text = em.EmpName,
Value = emp.Id.ToString() }).ToList();
I have two tables deal_outlet and vendors_outlet. I am trying to compare a list of outlet_id from deal_outlet table to vendor table but .contain method shows error has some invalid arguments. I really don't understand problem in this code.
public ActionResult Detail_of_deal(int id)
{
var d1 = db.deal_outlet.Where(x => x.outlet_id==id).ToList();
f_model.model4 = db.vendors_outlet.Where(x =>d1.Contains(x.outlet_id)).ToList();
var d = obj.detail_of_image(id,ref model);
return View(f_model);
}
Depending on the goal of the code you could try the following:
public ActionResult Detail_of_deal(int id)
{
var d1 = db.deal_outlet.Where(x => x.outlet_id==id).ToList();
f_model.model4 = db.vendors_outlet.AsEnumerable().Select(x => d1.Contains(x.outlet_id)).ToList();
var d = obj.detail_of_image(id,ref model);
return View(f_model);
}
That should make f_model.model4 a list of all the vendors_outlets that have a matching deal_outlet.id
The Linq Contains method returns true if the list contains the item passed in. You are asking to see if a list of deal_outlet objects contains an int, which obviously it won't.
Instead of projecting a collection of deal_outlets, project a list of integers:
var d1 = db.deal_outlet.Where(x => x.outlet_id==id).Select(x => x.outlet_id);
f_model.model4 = db.vendors_outlet.Where(x =>d1.Contains(x.outlet_id)).ToList();
But logically, that's the same as:
f_model.model4 = db.vendors_outlet.Where(x =>x.outlet_i==id)).ToList();
So it's not clear what you're trying to do.
EDIT
Based on your comments, I believe these are the queries you want:
i am trying to fetch list of outlet_id from deal_outlet table where deal_id equal to id,
var d1 = db.deal_outlet.Where(x => x.deal_id==id).ToList();
Now want to compare this list to vendor_outlet table and fetch those rows where outlet_id from deal_outlet table equals to outlet_id in vendor_outlet table
Get a list of ID's to match:
var ids = d1.Select(x => x.outlet_id).ToList();
And use Contains to see if the list contains any of the IDs from the related table:
f_model.model4 = db.vendors_outlet.Where(vo => ids.Contains(vo.outlet_id))
.ToList();
I have created a set of search results, and I wish to create a filter of available cats, with the number of results within that filter. however I get the most strangest error when trying to do this.
Unable to create a constant value of type 'NAMESPACE.Models.Products'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.
this is the code i have tried:
var cats = (from p in ctx1.SubCategories
where myCats.Contains(p.subCategoryId) && p.enabled
select new
AvailableSubCats
{
CategoryName = p.subCategoryName,
Id = p.subCategoryId,
TotalItems = model.Count(x => x.subCategoryId == p.subCategoryId)
}).Distinct();
Products is the object that is called model on the line of totalItems.
I have also tried this:
var cats = from c in ctx1.SubCategories
join p in model on c.subCategoryId equals p.subCategorySubId
group p by c.subCategoryName
into g
select new
AvailableSubCats
{
CategoryName = g.Key,
Id = 0,
TotalItems = g.Count()
};
with the same error, and dont like this because i dont know how to get the name of the category and its ID.
help much appreciated.
thanks
p.s I am using Entity framework 4.1, .net 4 and MVC 3, mysql
in short i am trying to run this in linq, but were the the products side is already a result
select c.*, (select count(productId) from Products where Products.subCategoryId = c.subCategoryId) as counter from SubCategories c
You could try turning your list of products into a list of subCategoryId's so EF can understand it. Something like:
var subCategoryIds = model.Select(m => m.subCategoryId);
var cats = (from p in ctx1.SubCategories
ctx1.SubCategories
where myCats.Contains(p.subCategoryId) && p.enabled
select new
AvailableSubCats
{
CategoryName = p.subCategoryName,
Id = p.subCategoryId,
TotalItems = subCategoryIds.Count(x => x == p.subCategoryId)
}).Distinct();
I want to select all categories from a webservice. The webservice does not have a method for that, so I have to get all products, then select all categories that these products are in. When I recieve the data from the webservice, I make WebServiceProduct (ID, Name, etc) and WebServiceCategory (ID, Name, etc) objects of it.
This does not work:
IQueryable<SelectListItem> categories = (from p in webserviceProductRepository.GetProducts()
from c in p.Categories
select new SelectListItem
{
Value = c.ID.ToString(),
Text = c.Name
}).Distinct().OrderBy(c => c.Text);
But it works when I first select it as a anonymus type:
var foo = (from p in webserviceProductRepository.GetProducts()
from c in p.Categories
select new
{
ID = c.ID.ToString(),
Name = c.Name
}).Distinct().OrderBy(c => c.Name);
IQueryable<SelectListItem> categories = from c in foo
select new SelectListItem
{
Value = c.ID.ToString(),
Text = c.Name
};
I have also tried with a IEqualityComparer and overrided Equals and GetHashCode to check on WebServiceCategory.ID, but it does not work either.
So my question are, why is Distinct() working better on a anonymus type than on my WebServiceCategory object and SelectListItem?
Anonymous types have value equality. Reference types have reference equality. LINQ to Entities is following the default semantics for the types. But overriding Equals or implementing IEquatable won't work, because LINQ to Entities queries are translated to SQL, and LINQ to Entities cannot translate arbitrary C# code to SQL. Note that the overloads of, e.g., Distinct which take a comparer aren't supported in L2E.
You have one workaround already, in your second code example. Another would be to group by an anonymous type:
var categories = from p in webserviceProductRepository.GetProducts()
from c in p.Categories
group c by new { Id = c.ID, Name = c.Name } into g
order by g.Key.Name
select new SelectListItem
{
Value = g.Key.Id.ToString(),
Text = g.Key.Name
};
Have you tried implementing IEquatable<T> on SelectListItem?
I think, its an IQueryable object and IEqualityComparer's wont work for this object. Maybe this will help
IQueryable<SelectListItem> categories = (from p in webserviceProductRepository.GetProducts()
from c in p.Categories.Distinct()
orderby c.Name
select new SelectListItem
{
Value = c.ID.ToString(),
Text = c.Name
});
Given a table of order items (OrderItems) that relates to a table of orders (Orders), which in turn relates to a table of users (Users), is it possible to retrieve all the OrderItems and group them into a dictionary by OrderId with just one query? ie. without performing an iteration over either the OrderItems result set or performing a query for each order.
Desired controller pseudo-code
Dictionary<int,IEnumerable<OrderItem>> OrderItems = DataContext.OrderItems.ToDictionary(Key => oi.OrderId, Value => oi.ToList());
Desired usage:
IEnumerable<OrderItem> currentOrderItems = OrderItems[123]; // where 123 is OrderId
Current Method
In my Controller I presently retrieve a user's orders and order items to pass to the Orders view:
ViewData["Orders"] = (from o in orders
where o.UserId equals CurrentUserId
orderby o.DateCreated descending)
.ToList();
ViewData["OrderItems"] = (from oi in DataContext.OrderItems
join o in DataContext.Orders
on oi.OrderId equals o.OrderId
where o.UserId equals CurrentUserId
select oi)
.ToList();
Then in my view, I retrieve all order items:
IEnumerable<OrderItem> orderItems = ViewData["OrderItems"] as IEnumerable<OrderItem>;
and use LINQ to group and display each order's order items:
IEnumerable<OrderItem> currentOrderItems = orderItems.Where(
i => i.OrderId == order.OrderId
);
This is fairly efficient as only two queries are passed to the database and some processing is done in the view. But ideally, this should be done in the controller.
Solved it! With ToLookup(...)
ViewData["OrderItems"] = (from oi in DataContext.OrderItems
join o in DataContext.Orders
on oi.OrderId equals o.OrderId
where o.UserId == UserId
select oi).ToLookup(oi => oi.OrderId, oi => oi);
And in my view:
ILookup<int,OrderItem> orderItems = ViewData["OrderItems"] as ILookup<int,OrderItem>;
foreach (Order order in orders)
{
DisplayOrder(order);
// Now display this order's items:
foreach(OrderItem item in orderItems[order.OrderId])
{
DisplayOrderItem(item);
}
}
A trace shows only one query to create the lookup.
Looks like I'm making a habit out of answering my own questions...
I think your best bet is to create a method that accepts a lambda for the key and a list to be inserted into the dictionary and then simply enumerates the list and adds to the dictionary using the key provided in the lambda. The method could be an Extension Method of IDictionary and let's call it say, AddRangeWithKeyType()