Conversion between IEnumerable EnumerableRowCollection - linq

I have the following code:
var aaData = myapi.GetData().AsEnumerable().Select(x => new {
Id = x["myID"],
Desc = x["myDesc"]
});
Trying to do the following
aaData = aaData.OrderBy((string.Join(",", request.Order
.Select(x => request.Columns[x.Column].Data + " " + x.Dir))));
Getting error:
CS0266 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<>' to 'System.Data.EnumerableRowCollection<>'. An explicit conversion exists (are you missing a cast?)
How to fix this?
GetData returns a DataTable
Request is an object having a property:
public OrderCol[] Order { get; set; }
OrderCol is
public class OrderCol {
public int Column { get; set; }
public string Dir { get; set; }
}
Thanks for your assistance.
The above code works for the case when I get a List<> back instead of DataTable. The error states that a Cast is needed and it seems to be how DataTable.AsEnumerable is set up as a EnumerableRowCollection
Can use a mock datatable to mimic the above
DataTable dt = new DataTable();
dt.clear();
dt.Columns.Add("myID");
dt.Columns.Add("myDesc");

all i needed was to convert to a list and things worked fine

Related

Linq Expressions on Child entities

I am building dynamic linq expressions which is working fine for a single entity.
For example:
I have a class called Employee and empeduinfo
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
public class EmpEduInfo
{
public int Id { get; set; }
public string Name { get; set; }
public int EmpId { get; set; }
}
I need to get all the the employees and empeduinfo class starts with "x"
I prepared expression for startswith("x")
var temp= entities.employees.Include("EmpEduInfo").Where(mydynamicexpression);
In this case it is filtering only parent table not on child.
I need to prepare generic expression so than i need to filter both parent and child objects dynamically.
Without using expression I know a solution:
var temp= (from ee in entities.Employee.Include("EmpEduInfo").Where(x => x.name.StartsWith("t"))
where ee.EmpEduInfo.Where(x => x.name.StartsWith("t")).Count()>0
select ee).ToList();
using expressions I am building generic expression to provide dynamic advance search rather than writing in each and every entity.
Here is my expression details
// Get the method information for the String.StartsWith() method
MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
// Build the parameter for the expression
ParameterExpression empparam= Expression.Parameter(typeof(employee), "ename");;
// Build the member that was specified for the expression
MemberExpression field = Expression.PropertyOrField(empparam, "name");
// Call the String.StartsWith() method on the member
MethodCallExpression startsWith = Expression.Call(field, mi, Expression.Constant("t"));
var namelamda = Expression.Lambda<Func<employee, bool>>(startsWith, new ParameterExpression[] { empparam });
var temp = entities.employees.Include("empedudetails").Where(namelamda).ToList();
You can look at the Expression the compiler generates using IQueryable:
IQueryable<Employee> query =
from ee in entities.Employee ...
var expression = query.Expression;
Look at expression in a debugger to see what you need to generate - LINQPad is good for this.
You might want to simplify your query a bit first:
IQueryable<Employee> query =
from ee in entities.Employee.Include("EmpEduInfo")
where
ee.name.StartsWith("t") &&
ee.EmpEduInfo.Any(x => x.name.StartsWith("t"))
select ee;
I was trying in EF 4.0 either we have write DB extentions for the same.
Option is provided in EF 4.1
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application
Thanks.

ASP.NET MVC change model data type in before send to view

I used Linq to Entity, for fetch a model from DB
var works = db.Work.Where(a => a.StartDate == DateTime.Now).ToList();
this model contain a DateTime that I want to change it to string before send it to view
beacuase need to show it as a persianDate Time,
like this :
foreach (var item in workslist)
{
item.StartDate = "1391/01/01"; //Just For Exapmle as you know this won't work
}
return View(workslist);
So is there any way to change a data type in a strongly typed model? or other way to do this except save DateTime as String in my DB
You can use the [DisplayFormat] attribute with EditorFor/DisplayFor helpers to format the data.
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy/mm/dd}")]
public DateTime StartDate { get; set; }
Then in view:
#Html.EditorFor(m => m.StartDate)
OR, you can also consider to define separate ViewModel for your 'Work' domain model. Though this approach results in more code, it's provide more flexibility and considered as good practice.
Here is sample code:
public class Work
{
public DateTime StartDate {get;set;}
}
public class WorkViewModel
{
public WorkViewModel()
{
}
public string StartDate { get; set; }
public static WorkViewModel Map(Work domainModel)
{
return new WorkViewModel() {
//Apply your Date format logic
StartDate = domainModel.StartDate.ToString("yyyy/MM/dd")
};
}
}
In action method:
var works = db.Work.Where(a => a.StartDate == DateTime.Now).ToList();
var workViewModels = new List<WorkViewModel>(works.Count);
foreach (var work in works)
workViewModels.Add(WorkViewModel.Map(work));
return View(workViewModels);
you can have a function in your controller to change datetime to string
public string changeDateTimeToPersianString ( DateTime time)
{
// your code
}
then you can call this function from your View.
in Razor something like this
#changeDateTimeToPersianString(workslistitem.StartDate)

how to pass selectmany combine with groupby to MVC view

i have the following lambda expression in MVC application.
var toprating= _db.Movie.SelectMany(m => m.Rating.Select(r=> new
{
movieID=r.MovieID,
MovieTitle= m.Title
})).GroupBy(m=>m.movieID).ToList();
ViewBag.TopMovie = toprating;
}
i want to pass this to my view.
i try writing the following in my view
IEnumerable<Movie> TopMovies = ViewBag.TopMovie;
but got this error
Cannot implicitly convert type 'object' to 'System.Collections.Generic.IEnumerable<Movie>'. An explicit conversion exists (are you missing a cast?)
any help will be appriciated.
i would recommend that you make a class that depicts your domain entity (Movie) like
public class MyMovie{
public int movieID { get; set; }
public string MovieTitle { get; set; }
}
and modify your linq query as
var toprating= _db.Movie.SelectMany(m => m.Rating.Select(r=> new MyMovie
{
movieID=r.MovieID,
MovieTitle= m.Title
})).GroupBy(m=>m.movieID).ToList();
ViewBag.TopMovie = toprating;
IEnumerable<MyMovie> TopMovies = ViewBag.TopMovie;
i have assumed that the Movie is your Domain entity, use view models to pass on to the views.
you may find this helpful

LINQ query returning a List<> as a class member

Given the follow data class,
public class EmployeeMenu
{
public int ID { get; set; }
public string HeaderName { get; set; }
public List<string> ItemNames { get; set; }
}
how can I get a sub-query into the ItemNames field?
My current query of
IQueryable<EmployeeMenu> retValue =
from mh in menuHeaders
select new EmployeeMenu
{
ID = mh.ID,
HeaderName = mh.HeaderName,
ItemNames = (from mhi in mh.MenuItems
select mhi.MenuItemName).ToList<string>()
};
doesn't seem to be doing the trick...
The data structure is
MenuHeaders MenuItems
----------- ---------
ID ID
HeaderName <-(FK)--MenuHeaderID
MenuItemName
I ended up just changing from a List to IEnumerable. This fixed it.
Wouldnt you want to just put a where in your sub-select to filter that down to all the menu items with the MenuHeaderID equals mh.HeaderName. You can just .Equals() with the StringComparison type if you want as well.
Here is an example...
IQueryable<EmployeeMenu> retValue =
from mh in menuHeaders
select new EmployeeMenu
{
ID = mh.ID,
HeaderName = mh.HeaderName,
ItemNames = (from mhi in mh.MenuItems
select mhi.MenuItemName where mhi.MenuHeaderID = mh.HeaderName).ToList<string>()
};
My guess is that your not initiliazing the list within your class. I basing this off the experience I was having with Nhibernate.
public class EmployeeMenu
{
public int ID { get; set; }
public string HeaderName { get; set; }
public List<string> ItemNames { get; set; }
public EmployeeMenu()
{
ItemNames=new List<string>();
}
}
Hope this helps.
Okay. Try replacing
(from mhi in mh.MenuItems
select mhi.MenuItemName).ToList<string>()
by
mh.MenuItems
.AsEnumerable()
.Select(mhi => mhi.MenuItemName)
.ToList()
I question if you want a where clause in there somewhere, but this should get you past the runtime exception.
Any time you see an error message of the form "LINQ to Entities does recognize the method ... and this method can not be translated into a store expression" LINQ to Entities is telling you that it can't figure out how to translate part of the expression tree into a SQL statement. This means you need to pull things client side so that LINQ to Entities doesn't try to translate something that it can't translate.

Linq to NHibernate projection to anon. type results in mystifying cast error

I have an TaxWork entity which is persisted using NHibernate. This entity has the following properties (among others):
public virtual TaxWorkType Type { get; set; } //Kctc.TaxWorkType is an enumeration
public virtual TaxWorkStatus Status { get; set; } //Kctc.TaxWorkStatus is an enumeration
public virtual LegalWorkPriority Priority { get; set; } //Kctc.LegalWorkType is an enumeration
public virtual User Handler { get; set; } //Kctc.BusinessLayer.Entities.User is another entity
public virtual int? CaseNumber { get; set; }
I am using Linq to NHibernate to pull of a subset of the tax work objects as follows (taxWorkRepository.All obviously returns an IQueryable):
foreach (TaxWork taxWork in taxWorkRepository.All.Where(x => x.CaseNumber == _caseNumber).OrderBy(x => x.DateCreated))
{
...
}
This works fine. I want to use projection in order to query only the columns that are required in this case. I am usnig the following code:
foreach (var taxWorkFragment in taxWorkRepository.All.Where(x => x.CaseNumber == _caseNumber).OrderBy(x => x.DateCreated).Select(x => new { Type = x.Type, DateCreated = x.DateCreated, Handler = x.Handler, Status = x.Status, Priority = x.Priority }))
{
...
}
However, I'm getting the following error when trying to create the anonymous type:
Invalid cast from 'Kctc.TaxWorkStatus' to 'Kctc.BusinessLayer.Entities.User'.
Where on earth is it getting the idea that it should be casting a TaxWorkStatus to a User?
Any suggestions whatsoever what might be going wrong?
Try to make like this:
foreach (var taxWorkFragment in taxWorkRepository.All.Where(x => x.CaseNumber == _caseNumber).OrderBy(x => x.DateCreated)
.Select(x => new TaxWork { Type = x.Type, DateCreated = x.DateCreated, Handler = x.Handler, Status = x.Status, Priority = x.Priority }))
{
...
}
It should help

Resources