I'm trying to understand a block of code from a school project, but I'm not understanding what this does.
I know that this is a controller method and is passing some information to the view?
Can you help me?
public ActionResult Index(int ? page, string sort) {
using(istecEntities ctx = new istecEntities()) {
var Persons = ctx.Persons.ToList()
.Select(p => new Person {
Num = p.num,
Name = p.Name,
Area = p.Area,
Grades = p.Grades as List <Grade>
}).ToList<Person>();
switch (sort) {
case "numdesc":
Persons = Persons.OrderByDescending(p =>p.Num).ToList<Person>();
break;
case "NameDesc":
Persons = Persons.OrderByDescending(p =>p.Name).ToList<Person>();
break;
case "NameAsc":
Persons = Persons.OrderBy(p =>p.Name).ToList<Person>();
break;
default:
Persons = Persons.OrderBy(p =>p.Num).ToList<Person>();
break;
}
ViewBag.sortnum = (String.IsNullOrEmpty(sort)) ?
"numdesc": "";
ViewBag.sortName = (sort == "NameDesc") ?
"NameAsc": "NameDesc";
ViewBag.sort = sort;
int size = 3;
int pagenumber = (page ?? 1);
return View(Persons.ToPagedList<Person>(pagenumber, size));
}
}
Related
I want to populate a table using JSON data. This works perfectly.
However the issue occurs when I want to view the data. I keep on running into
'No property or field 'RegistrationIDasc' exists in type 'UserModel'.
My UserModel contains the string RegistrationID.I don't understand the addtional "asc".
This is the controller
public ActionResult LoadRolesData()
{
try
{
var draw = Request.Form.GetValues("draw").FirstOrDefault();
var start = Request.Form.GetValues("start").FirstOrDefault();
var length = Request.Form.GetValues("length").FirstOrDefault();
var sortColumn = Request.Form.GetValues("columns[" + Request.Form.GetValues("order[0][column]").FirstOrDefault() + "][name]").FirstOrDefault();
var sortColumnDir = Request.Form.GetValues("order[0][dir]").FirstOrDefault();
var searchValue = Request.Form.GetValues("search[value]").FirstOrDefault();
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordsTotal = 0;
var rolesData = _IAssignRoles.ShowallRoles(sortColumn, sortColumnDir, searchValue);
recordsTotal = rolesData.Count();
return Json(new { draw, recordsFiltered = recordsTotal, recordsTotal });
}
catch (Exception)
{
throw; //exception thrown here
}
}
Below is the class model
public IQueryable<UserModel> ShowallRoles(string sortColumn, string sortColumnDir, string Search)
{
var result = (from AssignedRoles in db.AssignedRoles
join registration in db.Registration on AssignedRoles.RegistrationID equals registration.RegistrationID
join AssignedRolesAdmin in db.Registration on AssignedRoles.AssignToAdmin equals AssignedRolesAdmin.RegistrationID
select new UserModel
{
Name = registration.Name,
AssignToAdmin = string.IsNullOrEmpty(AssignedRolesAdmin.Name) ? "*Not Assigned*" : AssignedRolesAdmin.Name.ToUpper(),
RegistrationID = registration.RegistrationID
});
if (!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDir))) //first exception thrown
{
result = result.Where(sortColumn + "" + sortColumnDir);
}
if (!string.IsNullOrEmpty(Search))
{
result = result.Where(m => m.Name == Search);
}
return result;
}
Pseudo code
public IQueryable<UserModel> ShowallRoles(string sortColumn, string sortColumnDir, string Search)
{
var result = (from AssignedRoles in db.AssignedRoles
join registration in db.Registration on AssignedRoles.RegistrationID equals registration.RegistrationID
join AssignedRolesAdmin in db.Registration on AssignedRoles.AssignToAdmin equals AssignedRolesAdmin.RegistrationID
select new UserModel
{
Name = registration.Name,
AssignToAdmin = string.IsNullOrEmpty(AssignedRolesAdmin.Name) ? "*Not Assigned*" : AssignedRolesAdmin.Name.ToUpper(),
RegistrationID = registration.RegistrationID
});
if (!string.IsNullOrEmpty(Search))
{
result = result.Where(m => m.Name == Search);
}
if (!string.IsNullOrEmpty(sortColumn))
{
if (!string.IsNullOrEmpty(sortColumnDir))
{
if(sortColumnDir == "asc")
result = result.OrderBy(sortColumn);
else
result = result.OrderByDescending(sortColumn);
}
}
return result;
}
i'm using Datatables Jquery Extension and i've made multicolum sorting reading those posts:
http://www.codeproject.com/Articles/155422/jQuery-DataTables-and-ASP-NET-MVC-Integration-Part#Sorting
http://farm-fresh-code.blogspot.it/2012/02/mvc-jquery-ui-and-datatable-pluginajax.html
My question is, those two methods are dependent to The model that i'm using in my Controller, in this case
If i need to use similar code in other controllers i need to replicate that and changing model fields and the Type with others, for example .
This seems to me not very DRY.
How to Proceed? Is controller the good position for those two methods?
private IOrderedQueryable<User> CreateSortedQuery(DataTableParameterModel parameterModel, IQueryable<User> baseQuery)
{
var orderedQuery = (IOrderedQueryable<User>)baseQuery;
for (int i = 0; i < parameterModel.iSortingCols; ++i)
{
var ascending = string.Equals("asc", parameterModel.sSortDir[i], StringComparison.OrdinalIgnoreCase);
int sortCol = parameterModel.iSortCol[i];
Expression<Func<User, string>> orderByExpression = GetOrderingFunc(sortCol);
if (orderByExpression != null)
{
if (ascending)
{
orderedQuery = (i == 0)
? orderedQuery.OrderBy(orderByExpression)
: orderedQuery.ThenBy(orderByExpression);
}
else
{
orderedQuery = (i == 0)
? orderedQuery.OrderByDescending(orderByExpression)
: orderedQuery.ThenByDescending(orderByExpression);
}
}
else
{
if (ascending)
{
orderedQuery = (i == 0)
? orderedQuery.OrderBy(c => c.Id)
: orderedQuery.ThenBy(c => c.Id);
}
else
{
orderedQuery = (i == 0)
? orderedQuery.OrderByDescending(c => c.Id)
: orderedQuery.ThenByDescending(orderByExpression);
}
}
}
return orderedQuery;
}
private Expression<Func<User, string>> GetOrderingFunc(int ColumnIndex)
{
Expression<Func<User, string>> InitialorderingFunction;
switch (ColumnIndex)
{
case 1:
InitialorderingFunction = c => c.FirstName;
break;
case 2:
InitialorderingFunction = c => c.LastName;
break;
case 3:
InitialorderingFunction = c => c.UserName;
break;
case 4:
InitialorderingFunction = c => c.Email;
break;
case 5:
InitialorderingFunction = c => c.BusinessName;
break;
default:
InitialorderingFunction = null;
break;
}
return InitialorderingFunction;
}
I guess, your question is pretty close to these two answers:
Property name evaluating from expression:
public static RouteValueDictionary GetInfo<T,P>(this HtmlHelper html, Expression<Func<T, P>> action) where T : class
{
var expression = (MemberExpression)action.Body;
string fieldName = expression.Member.Name;
and
Applying linq sorting passing string values with LINQ Dynamic Query Library:
var result = data
.Where(/* ... */)
.Select(/* ... */)
.OrderBy(fieldName + " asc");
I have the following index action method which display a list of objects as follow:-
public ActionResult Index(string searchTerm = "", int page = 1)
{
string withOutSpace = searchTerm.Trim();
ViewBag.searchTerm = searchTerm;
int pagesize;
bool succeed = int.TryParse(System.Web.Configuration.WebConfigurationManager.AppSettings["TechPageSize"], out pagesize);
var racks = repository.AllFind(withOutSpace).OrderBy(a => a.Technology.SerialNumber).ToPagedList(page, pagesize);
currently I am always ordering by the SerialNumber, but my question is how I can pass a parameter to my index actionmethod and do the OrderBy based on the passed parameter, such as price, date, etc.
can anyone advice?
And second question how I can make the first call to orberby ascending while the second call to do the order descending ?
Thanks
public ActionResult Index(string searchTerm = "", string sort, bool asc, int page = 1)
{
string withOutSpace = searchTerm.Trim();
ViewBag.searchTerm = searchTerm;
int pagesize;
bool succeed = int.TryParse(System.Web.Configuration.WebConfigurationManager.AppSettings["TechPageSize"], out pagesize);
var racks = repository.AllFind(withOutSpace);
if(asc)
{
switch(sort)
{
case "price":
racks = racks.OrderBy(a => a.Technology.Price);
break;
case "date":
racks = racks.OrderBy(a => a.Technology.Date);
break;
case default:
racks = racks.OrderBy(a => a.Technology.SerialNumber);
break;
}
}
else
{
switch(sort)
{
case "price":
racks = racks.OrderByDescending(a => a.Technology.Price);
break;
case "date":
racks = racks.OrderByDescending(a => a.Technology.Date);
break;
case default:
racks = racks.OrderByDescending(a => a.Technology.SerialNumber);
break;
}
}
racks = racks.ToPagedList(page, pagesize)
you can use reflection inside the orderBymethod..something like
racks.OrderBy(a => {
//use reflection get the property
PropInfo prop = a.GetType().GetProperty("price");
return prop;
})
I haven't tested this code..this just an idea..
I am doing WP8 with sqlite-net. Sometime I wish to make a raw query without defining Table Model everytime.
What I did is is make a query below, and try to get its property:
string query = "SELECT firstname, lastname FROM users";
var records = db.Query<object>(query).ToList();
foreach (var r in records)
{
System.Diagnostics.Debug.WriteLine(r.GetType().GetProperty("firstname").GetValue(r,null).toString());
}
However, an Exception of "System.NullReferenceException" happens.
May I know how do I actually get the value without declaring Table Model?
Simply:
string query = "SELECT firstname, lastname FROM users";
Statement stQuery = SQLite3.Prepare2(connection.Handle, query);
while ((SQLite3.Result result = SQLite3.Step(stQuery)) == SQLite3.Result.Row)
{
//your stuff here
}
SQLite3.Finalize(stQuery);
you can extend the partial class in this way:
namespace SQLite
{
public partial class SQLiteConnection
{
public List<object[]> CustomQuery(string query, params object[] args)
{
var cmd = CreateCommand(query, args);
return cmd.ExecuteCustomQuery();
}
}
public partial class SQLiteCommand
{
public List<object[]> ExecuteCustomQuery()
{
if (SQLiteConnection.Trace)
{
Debug.WriteLine("Executing Query: " + this);
}
var stmt = Prepare();
try
{
var colLenght = SQLite3.ColumnCount(stmt);
var lstRes = new List<object[]>();
while (SQLite3.Step(stmt) == SQLite3.Result.Row)
{
var obj = new object[colLenght];
lstRes.Add(obj);
for (int i = 0; i < colLenght; i++)
{
var colType = SQLite3.ColumnType(stmt, i);
switch (colType)
{
case SQLite3.ColType.Blob:
obj[i] = SQLite3.ColumnBlob(stmt, i);
break;
case SQLite3.ColType.Float:
obj[i] = SQLite3.ColumnDouble(stmt, i);
break;
case SQLite3.ColType.Integer:
obj[i] = SQLite3.ColumnInt(stmt, i);
break;
case SQLite3.ColType.Null:
obj[i] = null;
break;
case SQLite3.ColType.Text:
obj[i] = SQLite3.ColumnString(stmt, i);
break;
}
}
}
return lstRes;
}
finally
{
SQLite3.Finalize(stmt);
}
}
}
}
and after you have a method that return a list of array of object that you can call in this way:
var query = "select c.Id, c.Name, (select count(*) from Products where IdCategory = c.Id) from Categories c order by c.Name";
var lst = this.SqlConn.CustomQuery(query);
return (from s in lst
select new CategoryDescriptor {
Id = (int) s[0],
Name = (string) s[1],
ProductsCount = (int) s[2]
});
Using the top two answers (first answer required changing the source code, and second was incomplete)
I came up with this method:
public List<object[]> RunSql(string sqlString, bool includeColumnNamesAsFirstRow)
{
var lstRes = new List<object[]>();
SQLitePCL.sqlite3_stmt stQuery = null;
try
{
stQuery = SQLite3.Prepare2(fieldStrikeDatabase.Connection.Handle, sqlString);
var colLenght = SQLite3.ColumnCount(stQuery);
if (includeColumnNamesAsFirstRow)
{
var obj = new object[colLenght];
lstRes.Add(obj);
for (int i = 0; i < colLenght; i++)
{
obj[i] = SQLite3.ColumnName(stQuery, i);
}
}
while (SQLite3.Step(stQuery) == SQLite3.Result.Row)
{
var obj = new object[colLenght];
lstRes.Add(obj);
for (int i = 0; i < colLenght; i++)
{
var colType = SQLite3.ColumnType(stQuery, i);
switch (colType)
{
case SQLite3.ColType.Blob:
obj[i] = SQLite3.ColumnBlob(stQuery, i);
break;
case SQLite3.ColType.Float:
obj[i] = SQLite3.ColumnDouble(stQuery, i);
break;
case SQLite3.ColType.Integer:
obj[i] = SQLite3.ColumnInt(stQuery, i);
break;
case SQLite3.ColType.Null:
obj[i] = null;
break;
case SQLite3.ColType.Text:
obj[i] = SQLite3.ColumnString(stQuery, i);
break;
}
}
}
return lstRes;
}
catch (Exception)
{
return null;
}
finally
{
if (stQuery != null)
{
SQLite3.Finalize(stQuery);
}
}
}
I'm dynamically building a nhibernate projected query that needs to implement paging. Something like...
var projections = Projections.ProjectionList();
foreach (var p in projection.Projections)
{
IProjection newProjection = null;
switch (p.AggregateFunc)
{
case AggregateFuncTypeEnum.GroupProperty:
newProjection = Projections.GroupProperty(p.Path);
break;
case AggregateFuncTypeEnum.Sum:
newProjection = Projections.Sum(p.Path);
break;
default:
newProjection = Projections.Property(p.Path);
break;
}
projections.Add(newProjection, p.Name);
}
criteria.SetProjection(projections).SetResultTransformer(new AliasToBeanResultTransformer(projectionType));
I can get the first 15 results like so
criteria.SetFirstResult(0);
criteria.SetMaxResults(15);
var results = criteria.List();
But I also need to send another query to get the total number of records but so far I've failed to figure this out. The projection still needs to be applied i.e. if the results are grouped by 'code' with a sum of 'cost' then 100 records might return 20 rows, and it's the 20 I'm interested in.
How do I get the total number of records that will be returned? Thanks
maybe this:
var rowcount = CriteriaTransformer.Clone(criteria);
var goupprojections = Projections.ProjectionList();
var projections = Projections.ProjectionList();
foreach (var p in projection.Projections)
{
IProjection newProjection = null;
switch (p.AggregateFunc)
{
case AggregateFuncTypeEnum.GroupProperty:
newProjection = Projections.GroupProperty(p.Path);
goupprojections.Add(Projections.GroupProperty(p.Path), p.Name);
break;
case AggregateFuncTypeEnum.Sum:
newProjection = Projections.Sum(p.Path);
break;
default:
newProjection = Projections.Property(p.Path);
break;
}
projections.Add(newProjection, p.Name);
}
criteria.SetProjection(projections).SetResultTransformer(new AliasToBeanResultTransformer(projectionType));
if (goupprojections.Aliases.Length == 0)
{
rowcount.SetProjection(Projections.RowCount())
}
else
{
rowcount.SetProjection(Projections.Count(goupprojections))
}
var results = criteria.Future();
var count = rowcount.FutureValue<int>();