Mvc: Linq OrderBy custom parameter - asp.net-mvc

I have the next linq query
public IEnumerable<Table> GetTablePage(int pageNumber, int pageSize, string searchCriteria)
{
Entities db = new Entities();
if (pageNumber < 1)
{
pageNumber = 1;
}
return entities.Table.OrderBy(searchCriteria).Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();
}
It´s working fine, but i have some table fields where i need to do some joins for retrieving information, it's because in my Table i only have the code and i really need the name.
Example -> customerId is foreign key in Table, and i would like to get the customerName, but actually i can´t because entities.Table only has customerId, What´s the best way to return the information without losing Table.OrderBy(searchCriteria)... properties ? Thanks in advance.

I suppose that you are using Dynamic Linq to pass a string to your orderBy.
How do you filter your result with an OrderBy? i suppose that you try to filter using your searchCriteria?
Now some kind of answer might be....
If you include the child table in your query, then the child will be a part of your Table object.
entities.Table.Include("Customer").OrderBy(....

Related

Neo4jClient : C# query to fetch collection with multiple columns

How one can fetch multiple columns data using neo4jClient -
For eq. the example shown on link
Cyper query to fetch multiple column collection
The sample shown above passes properties of event node for collection instead of complete event node.
The query I am constructing takes few properties from the event node and few properties from the relation.
For eq. The relation attribute "registerd_on" needs to be added.
So how to pass multiple properties for collection ?
It's not very nice, but if you look at what is returned by doing a collection you get an array of arrays, but these arrays don't have properties as such, so you can only really parse them as string.
Using the :play movies dataset as a base:
var query = gc.Cypher
.Match("(p:Person {name:'Tom Hanks'})-->(m:Movie)")
.With("p, collect([m.title, m.released]) as collection")
.Return((p, collection) => new
{
Person = p.As<Person>(),
Collection = Return.As<IEnumerable<IEnumerable<string>>>("collection")
});
where Person is :
public class Person
{
public string name { get; set; }
}
You can then access the data like so:
foreach (var result in results)
{
Console.WriteLine($"Person: {result.Person.name}");
foreach (var collection in result.Collection)
{
foreach (var item in collection)
{
Console.WriteLine($"\t{item}");
}
}
}
which is not nice :/

MVC Enity Framework get KEY attribute from table

I am trying to extract the [key] value from a table.
This is for a logging method which looks like this:
private List<Log> GetAuditRecordsForChange(DbEntityEntry dbEntry, string userId)
{
List<Log> result = new List<Log>();
DateTime changeTime = DateTime.Now;
// Get the Table() attribute, if one exists
TableAttribute tableAttr = dbEntry.Entity.GetType().GetCustomAttributes(typeof(TableAttribute), false).SingleOrDefault() as TableAttribute;
// Get table name (if it has a Table attribute, use that, otherwise get the pluralized name)
string tableName = tableAttr != null ? tableAttr.Name : dbEntry.Entity.GetType().Name;
// Get primary key value
string keyName = dbEntry.Entity.GetType().GetProperties().Single(p => p.GetCustomAttributes(typeof(KeyAttribute), false).Count() > 0).Name;
if (dbEntry.State == EntityState.Added)
{
result.Add(new Log()
{
LogID = Guid.NewGuid(),
EventType = "A", // Added
TableName = tableName,
RecordID = dbEntry.CurrentValues.GetValue<object>(keyName).ToString(),
ColumnName = "*ALL",
NewValue = (dbEntry.CurrentValues.ToObject() is IDescribableEntity) ? (dbEntry.CurrentValues.ToObject() as IDescribableEntity).Describe() : dbEntry.CurrentValues.ToObject().ToString(),
Created_by = userId,
Created_date = changeTime
}
);
}
The problem is to get the RecordID when a Record is added, when it get deleted or modified it works. (The code to get it is the same)
When I debug I also see that it has the KeyAttribute in the CustomAttributes base but not sure why it always shows up as 0.
I can debug more if needed
After savechanges you can fetch the newly created key. (Guess the key is generated automatically inserting a new record).
for me you have several solutions.
first solution:
enlist added entity from the context
SaveChanges
enumerate the enlisted entities to add log
SaveChanges
the problem (or not) here is that the business and the logging are not in the same transaction.
antother problem, depending on the implementation, is to prevent loging of log of log of log... This can be donne by filtering entities by typeName for example.
other solution:
add and ICollection<Log> to your entities.
the problem here is to unify the logs:
inheritance of entity, or
several log tables + a view
...
other solution
use trigger at database level
other solution
..., use cdc if you have Sql Server Enterprise Edition

Filtering list using linq and mvc

Below is the code in question. I receive Object reference not set to an instance of an object. on the where clause inside the Linq query. However, this only happens after it goes through and builds my viewpage.
Meaning: If I step through using debugger, I can watch it pull the correct order I am filtering for, go to the correct ViewPage, fill in the model/table with the correct filtered item, and THEN it comes back to my Controller and shows me the error.
public ActionResult OrderIndex(string searchBy, string search)
{
var orders = repositoryOrder.GetOpenOrderList();
if (Request.QueryString["FilterOrderNumber"] != null)
{
var ordersFiltered = from n in orders
where n.OrderNumber.ToUpper().Contains(Request.QueryString["FilterOrderNumber"].ToUpper().ToString())
select n;
return View(ordersFiltered);
}
return View(orders);
}
its always better to manipulate your strings and other things outside the linq query ,
please refer : http://msdn.microsoft.com/en-us/library/bb738550.aspx
from the readability point of view also its not good ,
public ActionResult OrderIndex(string searchBy, string search)
{
var orders = repositoryOrder.GetOpenOrderList();
var orderNumber = Request.QueryString["FilterOrderNumber"];
if (!string.IsNullOrEmpty(orderNumber))
{
orderNumber = orderNumber.ToUpper();
var ordersFiltered = from n in orders
where n.OrderNumber.ToUpper().Contains(orderNumber)
select n;
return View(ordersFiltered);
}
return View(orders);
}
Your query is not being executed in your Action method because you don't have a ToList (or equivalent) added to your query. When your code returns, your query will be enumerated somewhere in your view and that's the point where the error occurs.
Try adding ToList to your query like this to force query execution in your action method:
var ordersFiltered = (from n in orders
where n.OrderNumber.ToUpper().Contains(Request.QueryString["FilterOrderNumber"].ToUpper().ToString())
select n).ToList();
What's going wrong is that a part of your where clause is null. This could be your query string parameter. Try moving the Request.QueryString part out of your query and into a temporary variable. If that's not the case make sure that your orders have an OrderNumber.
You both were right. Just separately.
This fixed my problem
var ordersFiltered = (from n in orders
where !string.IsNullOrEmpty(n.OrderNumber) && n.OrderNumber.ToUpper().Contains(Request.QueryString["FilterOrderNumber"].ToUpper().ToString())
select n);

LINQ to Entities query with join inside method for use in MVC app

In my Person table is a RequestedLocation column which stores location IDs. The IDs match the LocationId column in the Locations table, the Locations table also has the text location names, in the LocatioName column.
In my view, I need to display the string LocationName in the view which has the Person model passed to it. The view will be displaying a List of people in a telerik grid. CUrrently it works great, except the RequestedLocation column is all integers.
I am populating all my grids with methods containing LINQ queries. Here is the method that currently works:
public List<Person> GetPeople()
{
var query = from p in _DB.Person.ToList()
select p;
return query.ToList();
}
Here is the regular SQL query that works, and I need to convert into LINQ:
SELECT ApplicantID
,FirstName
,LastName
,MiddleName
,DateofBirth
,Gender
,RequestedVolunteerRole
,RequestedVolunteerLocation
,l.LocationName
FROM Form.Person p
JOIN dbo.Location l ON p.RequestedVolunteerLocation = l.LocationID
Order BY ApplicantID
Here is my attempt to convert to LINQ:
public List<NewApplicantViewModel> GetPeople()
{
var query = from pl in _DB.Person.ToList()
join l in _Elig_DB.Locations.ToList() on pl.RequestedVolunteerLocation equals l.LocationID
select new
{
pl.RequestedVolunteerLocation = l.LocationName
};
return query.ToList();
The number of errors I get from this are numerous, but most are along the lines of:
Cannot convert from type Annonymous to Type List<NewAPplicantModel>
and
Invalid annonymous type declarator.
Please help, and thank you for reading my post.
Oh, and I have only been programming for a couple months, so if I am going about this all wrong, please let me know. Only thing I have to stick with is the table structure because it is an existing app that I am updating, and changing the location or person tables would have large consequences.
public List<NewApplicantViewModel> GetPeople()
{
var query = from pl in _DB.Person
join l in _Elig_DB.Locations on pl.RequestedVolunteerLocation
equals l.LocationID
select new NewApplicantViewModel
{
LocationName = l.LocationName,
otherPropery = p.Property
};
return query.ToList();
}
Beware of calling _DB.Person.ToList() it will load all persons from DB because ToList() immediately executes the query and the join would be performed in memory (not in DB).
The reason you are getting an error is you are projecting an anonymous type
select new
{
pl.RequestedVolunteerLocation = l.LocationName
};
Instead, you need to project a NewApplicantViewModel
select new NewApplicantViewModel
{
RequestedVolunteerLocation = l.LocationName
};

How do I use 2 include statements in a single MVC EF query?

I am trying to write a query that includes 2 joins.
1 StoryTemplate can have multiple Stories
1 Story can have multiple StoryDrafts
I am starting the query on the StoryDrafts object because that is where it's linked to the UserId.
I don't have a reference from the StoryDrafts object directly to the StoryTemplates object. How would I build this query properly?
public JsonResult Index(int userId)
{
return Json(
db.StoryDrafts
.Include("Story")
.Include("StoryTemplate")
.Where(d => d.UserId == userId)
,JsonRequestBehavior.AllowGet);
}
Thank you for any help.
Try to flatten your hierarchy if it works for you. Here is a sample, and you may want to customize it for your needs.
var result = from c in db.Customers
join o in db.Orders
on c equals o.Customers
select new
{
custid = c.CustomerID,
cname = c.CompanyName,
address = c.Address,
orderid = o.OrderID,
freight = o.Freight,
orderdate = o.OrderDate
};
If flattering does not meet your requirements then you need to use query that returns a Nested Group. Finally, look at the following link for more references - LINQ Query Expressions .

Resources