Include("myTable") in Linq to Entities in Silverlight - c#

I need help, I have a method to Access to my Orders table:
public IQueryable<Orders> GetOrders()
{
return this.ObjectContext.Orders.Include("UnitDetail");
}
it Works very well, and I can see it from the window Data Source, and can see Orders and UnitDetail from here
But I need make some considerations for the selected rows, so I made the next method:
public IQueryable<Orders> GetOpenOrders(string _iduni)
{
ObjectSet<Orders> orders = this.ObjectContext.Orders;
ObjectSet<Estatus> estatus = this.ObjectContext.Estatus;
ObjectSet<DetailUnit> units = this.ObjectContext.DetailsUnit;
ObjectSet<ServiceType> servicetype = this.ObjectContext.ServiceType;
var query =
(from o in orders
join e in estatus on o.ID equals e.IDOrder
join u in units on o.IDUni equals u.IDUni
join t in servicetype on u.IDType equals t.IDType
where o.IDUni.Equals(_iduni)
&& !estatus.Any(oe => (oe.Estatus == "CANCELADA" || oe.Estatus == "CERRADA")
&& oe.IDOrder == o.ID)
select o).Distinct();
return query.AsQueryable();
}
This show me the correct recs, but what happend? why I don't see UnitDetail, when I inspect the result UnitDetail is null, how I can do for put the Include clausule in this new method??
Thanks a lot in advance

Because you haven't put the Include in your new method anywhere.
EDITED: to remove the unused joins.
You should be able to just use Include as you did in your GetOrders method, and so have it as a part of your existing orders variable. You are not actually using those joins anywhere, are you intending to?
Like this:
public IQueryable<Orders> GetOpenOrders(string _iduni)
{
var query =
(from o in this.ObjectContext.Orders.Include("UnitDetail")
where o.IDUni.Equals(_iduni)
&& !this.ObjectContext.Estatus.Any(oe => (oe.Estatus == "CANCELADA" || oe.Estatus == "CERRADA")
&& oe.IDOrder == o.ID)
select o).Distinct();
return query.AsQueryable();
}

Related

Filtering a IQueryable with results from another table

I have an EF query which gets products from the database.
var query = (from pPrice in db.ProductPricing
join prod in db.Products on pPrice.ProductID equals prod.ProductID
join productExt in db.ProductsExt on prod.ProductID equals productExt.ProductID into pExts
from prodExt in pExts.DefaultIfEmpty()
where (includeNonPublic || pPrice.ShowOnline == 1)
&& ((eventID.HasValue && pPrice.EventID == eventID) || (!eventID.HasValue && !pPrice.EventID.HasValue))
orderby prod.DisplayOrder
select new ProductPricingInfo()
{
Product = prod,
ProductPricing = pPrice,
ProductExtension = prodExt
});
I have a table where I can specify add-on products (products which can be bought once the parent item has been bought).
My query to fetch these add-on products is
var addOnProductsQuery = (from pa in db.ProductAddons
where pa.EventID == eventID && pa.StatusID == 1
select new { ProductID = pa.ChildProductId });
Now what I am trying to do is filter on the query variable to only return products which are not in the addOnProductsQuery result.
Currently I have
var addOnProducts = addOnProductsQuery.ToList();
query = query.Where(e => !addOnProducts.Contains(e.Product.ProductID));
But there is a syntax error on the Contains(e.Product.ProductID)) statement
Argument 1: cannot convert from int to anonymous type: int ProductID
Chetan is right in the comments, you need to select the integer from the object before using Contains.
You can do it in 2 ways:
First you could just take the integer initially:
var addOnProductsQuery = (from pa in db.ProductAddons
where pa.EventID == eventID && pa.StatusID == 1
select new pa.ChildProductId);
This should give int as type so you can use Contains later with no problem.
Second, if you want to keep the addOnProductsQuery unchanged:
var addOnProducts = addOnProductsQuery.Select(a => a.ProductID).ToList();
query = query.Where(e => !addOnProducts.Contains(e.Product.ProductID));

Excuting query: "LINQ to Entitites does not recognize method 'System.Object getItem(System.String)'"

First of all, I have these models:
I got this query in my controller and I want to put the query result into the view model:
var query = (from d in db.ObjectCategories
join a in db.MatchingObjects on d.Id equals a.ObjectCategoryId into grp3
join b in db.Unlocks
on d.Id equals b.ObjectCategoryId into grp1
from m in grp1.DefaultIfEmpty()
join c in db.Members
on m.StudentId equals c.Id into grp2
from n in grp2.DefaultIfEmpty()
where m.ObjectCategoryId == null
&& n.Id == null
&& n.Id == (int)Session["UserId"]
orderby d.Id
select new LockedCatListViewModel()
{
AnimalCategory = d.CategoryName,
AnimalCategoryId = d.Id,
Animals = d.MatchingObjects
}).AsEnumerable()
.Select(x=> new LockedCatListViewModel()
{
AnimalCategory = x.AnimalCategory,
AnimalCategoryId = x.AnimalCategoryId,
Animals = x.Animals
});
return View(query.ToList());
The View Model:
public class LockedCatListViewModel
{
[Display(Name = "Animal Category Name")]
public string AnimalCategory { get; set; }
public int AnimalCategoryId { get; set; }
public virtual ICollection<MatchingObject> Animals { get; set; }
}
However, whenever I want loop the item inside the Model in view page, or just return this model to the view page, I got the following error:
I have tried many different methods, I wonder what should be done inside my LINQ query in order to get the result of my LINQ query?
Problem solved by assigning the Session into a variable, and put the variable inside the Linq.
I think I have an incorrect LINQ query for this part
&& n.Id == null
&& n.Id == (int)Session["UserId"]
It seems there is a number of issues. Firstly the error is must likely due to the call to Session in your linq.
So to solve this move the session call outside of the linq statement and assign to a variable.
int userId = (int)Session["userId"];
You can then use the userId variable in place of the session call.
I think you will still find issue with your query after this because of these lines:
&& n.Id == null
&& n.Id == (int)Session["UserId"] //or userId when you change it
How can the n.Id be null and a value?

build dynamic linq query in where clause

I want to build a dynamic query that able to extend the where clause condition if the value of the object is not empty string. Here is the code
public IEnumerable<Filter> GetFilter(Filter filter)
{
var y = ConditionalAttribute(filter);
var query =
from sub in Subscriptions
join u in Users
on sub.UserID equals u.Id
join od in Order_Details1
on sub.OD_Id equals od.OD_Id
join p in Products
on od.ProductId equals p.ProductId
where p.Type == "Testing" + y
select new Filter
{
//do something
};
for the Filter Object, here is the code
public class Filter
{
public int UserId { get; set; }
public string FirstName { get; set;}
}
the idea is if the filter.FirstName is not null it will append the where clause like this
public String ConditionalAttribute(Filter filter)
{
if(filter.FirstName != "")
return "&& u.First_Name = " + filter.FirstName + "";
}
Is there any way to append where clause by string like the code above? Because I've tried the approach above and it fails thanks
Create as many dynamic terms as you want to use in small methods that return an IQueryable.
public IQueryable ConditionalAttribute(IQueryable query, Filter filter)
{
if(filter.FirstName != "") {
query = query.Where(x => x.First_Name == filter.FirstName);
}
return query;
}
then apply them after the initial LINQ statement as you require:
public IEnumerable<Filter> GetFilter(Filter filter)
{
var query =
from sub in Subscriptions
join u in Users
on sub.UserID equals u.Id
join od in Order_Details1
on sub.OD_Id equals od.OD_Id
join p in Products
on od.ProductId equals p.ProductId
where p.Type == "Testing"
select new Filter
{
//do something
};
query = ConditionalAttribute(query, filter);
The statement isn't going to run until you project it into by using .ToList() or FirstOrDefault() or something like that so you can keep chaining onto query in this way as many times as you need.
I tend to prefer using standard C# syntax rather than the LINQ syntax, but, having said that, I find that LINQ syntax is more elegant when it comes to joining queries.
Here's an approach which utilizes the standard C# syntax to dynamically filter the source containers, then uses LINQ syntax to create the joining query.
public IEnumerable<Filter> GetFilter(Filter filter)
{
var y = ConditionalAttribute(filter);
IEnumerable<User> filteredUsers = Users;
if(!string.IsNullOrEmpty(filter.FirstName))
{
filteredUsers = filteredUsers.Where(u => u.First_Name == filter.FirstName);
}
var query =
from sub in Subscriptions
join u in filteredUsers
on sub.UserID equals u.Id
join od in Order_Details1
on sub.OD_Id equals od.OD_Id
join p in Products
on od.ProductId equals p.ProductId
where p.Type == "Testing" + y
select new Filter
{
//do something
};

Writing the LINQ equaivalent of a SQL join

This is the SQL query I have written:
select * from Addresses a
join ProviderAddresses pa on a.address_k = pa.address_k
where pa.provider_k = 'ABC123'
and pa.active = 1
and a.active = 1
and pa.addresstype_rtk = 'HOME'
And this is the LINQ query I wrote for it:
public IQueryable<Addresses> GetAddressesesForProvider(string provider_k, string addresstype_rtk)
{
var query = from a in this.Context.Addresses
join pa in this.Context.ProviderAddresses on a.Address_K equals pa.Address_K
where pa.AddressType_RTK == addresstype_rtk
&& pa.Active == true
&& a.Active == true
select a;
return query;
}
But it is wrong. The LINQ one return thousands of records and the SQL one returns only one record.
It is IQueryable because later I need to go through its results with a for-each loop.
In the SQL I am passing hard coded values for testing but in my code for me LINQ method I also pass the same hard coded values so that is not the issue.
Looks like you may have just missed adding the provider_k condition to the where;
public IQueryable<Addresses> GetAddressesesForProvider(string provider_k, string addresstype_rtk)
{
var query = from a in this.Context.Addresses
join pa in this.Context.ProviderAddresses on a.Address_K equals pa.Address_K
where pa.Provider_K == provider_k &&
pa.AddressType_RTK == addresstype_rtk &&
pa.Active == true &&
a.Active == true
select a;
return query;
}

LINQ OrderBy query

I have the following that pulls through a list of suppliers:
public List<tblSupplierPerformance> GetSupplierInfo(string memberid, string locationid, string supplieridname)
{
MyEntities suppliers = new MyEntities();
var r = (from p in suppliers.tblSupplierPerformances
where p.MemberId == memberid && p.LocationId == locationid
orderby p.TotalPurchaseQuantity
select p)
.Distinct();
if (supplieridname != "0")
r = r.Where(p => p.SupplierIDName == supplieridname);
return r.ToList();
}
However, when this runs, the orderby doesn't seem to be ordering.
I think, think, I need to implement the orderby at the "return r." stage, but I don't really know how to do this or I could be very much wrong all over the shop!
Any pointers gladly received.
I suspect it's the Distinct call which is messing up the ordering... although as you're not joining or doing anything like that, I'm not sure why you need distinct - isn't each entity naturally distinct?
Anyway, you could certainly move the ordering to the return statement:
return r.OrderBy(p => p.TotalPurchaseQuantity).ToList();
Yes, you need to implement order by in the return
return r.ToList().OrderBy(o => o.Column1);

Categories

Resources