ASP.NET MVC2 Simple Linq Question - linq

I have the following code:
public ActionResult ViewCategory(string categoryName, string searchCriteria = "Price")
{
// Retrieve Category and its associated Listings from the database
var categoryModel = db.Categories.Include("Listings")
.Single(c => c.Title == categoryName);
var viewModel = new ClassifiedsBrowseViewModel
{
Category = categoryModel,
Listings = categoryModel.Listings.ToList()
};
return View(viewModel);
}
This code returns some listings from a given category.
But I want to re-order these search results based on certain criteria. E.G. Price...
Many Thanks,
J

You want to use OrderBy() or OrderByDescending() depending upon on requirements.
For example ordering it by highest price -
var viewModel = new ClassifiedsBrowseViewModel
{
Category = categoryModel,
Listings = categoryModel.Listings.OrderByDescending(c=>c.Price).ToList()
};

Listings = categoryModel.Listings.OrderBy(x => x.Price).ToList();

Another option that might work, depending on how you present the information: use something like the jquery tablesorter plugin, and sort the results on the client side.
Obviously, this won't work if there are a lot of results, and you're doing paging, but for a single page of results, presented in a table, it works great.

Another way to write the Linq is to use the query language:
Listings = from item in categoryModel.Listings
orderby item.Price
select item;

Related

mvc 3 return view with other objects

I have a details page that returns a profile view that is basically used to find the page number from the database. I also have a separate query that I would like to return in the return view but cannot figure out how to. The code I have is
public ActionResult detail(int id)
{
profile profile = db.profiles.Find(id);
var currentpage = (from s in db.profiles where id == s.profileID select s.registrationID).FirstOrDefault();
var articles = (from s in db.Articles where currentpage == s.RegistrationID select s.title).FirstOrDefault();
ViewBag.articles = articles;
ViewBag.noprofiler = " This profile currently doesn't have the email profiler selected";
return View(profile);
}
i would like to also return articles i put it into a viewbag but that is not working any ideas ?
If articles is populated then you should be able to access it in the view via ViewBag.articles
Maybe you should check what is in the articles variable here in the controller function.
Also the variable name articles suggests you're looking for a list but you are using FirstOrDefault() which would return a single object (or null).

Get rid of duplicate entries in autocomplete

I am having difficulty getting rid of duplicate entries which are showing up in autocomplete.
The autocomplete is generated dynamically from a database.
This is the code which is being used for the autocomplete in the control:
public ActionResult AutoCompletefootball()
{
var db = new footEntities();
string selection = this.Request.Params["term"].ToString();
return Json(db.football.Where(a => a.player.Name.StartsWith(selection)).Select(Adds => a.Player.Name), JsonRequestBehavior.AllowGet);
}
All advice welcome
In your return statement (where you use LINQ), add DISTINCT clause.
.Distinct() will eliminate duplicates, but consider that duplicates are appearing because there are many players with the same name, so they are not really duplicate people

What is the controller syntax for sorting multiple MvcContrib Grids?

I can't quite figure out the syntax for sorting multiple MvcContrib grids. I know the recommendation from Jeremy Skinner here is to use the Bind attribute but I just can't get it right.
Here is my controller:
public ActionResult Index([Bind](Prefix="grid1")GridSortOptions sort)\\how do I reference the prefix of my second grid?
{
ViewData["sort"] = sort;
var products = _productService.GetAllProducts();
var categories = _categoryService.GetAllCategories();
//Here is where I am stuck
if(sort.Column != null)
{
products = products.OrderBy(sort.Column, sort.Direction);
//how do I reference the sort columns of my second grid?
}
var model = new ContainerModel
{
Products = products,
Categories = categories
};
return View(model);
}
I guess I really don't understand everything about the Bind attribute. I tried adding a second GridSortOptions argument but that was not successful.
Here are my views if this helps.
.Sort((GridSortOptions)ViewData["sort"], "grid1")//Grid 1
.Sort((GridSortOptions)ViewData["sort"], "grid2")//Grid 2
Any ideas? Thanks.
I figured out my problem from my post:
MVCContrib Grid - Sort(GridSortOptions, prefix) not generating links for sorting
It is possible that the default binder is not pre-populating your parameters and so your GridSortoptions are probably null which means no links ultimately.
Also, just create a second GridSortOptions parameter for the second grid and use that in the call to Sort().

How to apply global filter on Entity Framework?

I have a table in my model named Customers with a field IsActive. Whenever I run a query on Customers, only the active customers should be retrieved. I can include the filter in every query, but that doesn't look very. I would like to be able to override the Customers property at the Object Context lever, but I am not sure if this is possible. Any help would be very appreciated! Thanks
Although a late response, I will put it here so it can help others.
You can also set a condition for your entity in your edmx file. Select your entity and Goto Mapping Details and create a new condition.
Maybe you could declare new property and use it:
public partial class MyEntities
{
public ObjectQuery<User> ActiveCustomers
{
get
{
return Customers.Where(c => c.IsActive);
}
}
}
I don't know why this is problem for you. You can put one query inside some function:
IEnumerable<Customers> GetActiveCustomers()
{
var activeCustomers =
from cust in db.Customers
where cust.IsActive == true
select cust;
return activeCustomers;
}
And call it every time you like. You can even put active customers in some private List or even better ObservableCollection. Then you can query your result again:
var myCustomers =
from cust in GetActiveCustomers()
where cust.CustomerName == "John"
select cust;
and that's it.
All you need to do is retrieve all of the customers no matter if they are active or not and then use a
foreach(Customer c in Results)
{
if(c.IsActive)
listofactivecustomers.Add(c);
}

LINQ query for tag system: Matching any of several tags?

I am just getting started with LINQ. I am creating an Entity Framework app that uses the canonical Post and Tag model. A Post contains an ID, Text, and Tags, and a Tag contains an ID, a Name, and Posts.
A previous thread on StackOverflow showed me how to query for a Post that matches all Tag objects (A and B and C) in a search list. But how would I query for a Post that matches any Tag (A or B or C) in the list? Thanks for your help.
Stumbled over the answer right after I posted this question. PredicateBuilder to the rescue!
Here's my code, which uses PredicateBuilder. It is set up as an extension method:
public static IQueryable<Note> WhereContainsAnyTags(this IQueryable<Note> notes, IEnumerable<Tag> searchTags)
{
// Initialize
var predicate = PredicateBuilder.False<Note>();
// Select Notes that contain any search Tags
foreach (var searchTag in searchTags)
{
var tag = searchTag;
predicate = predicate.Or(note => note.Tags.Any(t => t.Id == tag.Id));
}
// Set return value
return notes.AsExpandable().Where(predicate);
}
And here is how I call the code:
searchResults = m_ViewModel.ObjectContext.Notes.WhereContainsAnyTags(m_ViewModel.SearchTags);
Not sure if this would work or not, but worth a try anyway I guess if you are already using WhereIn.
var posts = context.Tags.WhereIn(tag => tag.Name, acceptableValues)
.SelectMany(t => t.Posts);
The WhereIn should give you all the tags that are part of the name, and the SelectMany should give you all the posts containing those tags.
You could aslo do it like this with Entity SQL
var post = ctx.Posts.Where("it.Tags.Id IN (1,2,3)");

Resources