How Can I pass a Data list to CreateAsync Func? - c#

I have a problem with CreateAsync, it wants IOrderedQueryable.
I need to read just two records (Id,Title) from my News table and pass them to my ViewModel but it doesn't let me pass RetValue (list type) in CreateAsync.
var MyNews = _context.News.Select(news => new
{
news.Id,
news.Title,
}).AsNoTracking().OrderByDescending(p => p.Id);
List<ListNewsViewModel> RetValue = new List<ListNewsViewModel>();
foreach (var item in MyNews)
{
ListNewsViewModelLN = new ListNewsViewModel();
LN.Id = item.Id;
LN.Title = item.Title;
RetValue.Add(LN);
}
var model = await PagingList.CreateAsync(RetValue, 10, PageIndex);
model.Action = "EditNews";
return View(model);

You can try to do like this:
var MyNews = (from q in _context.News
select new ListNewsViewModel()
{
Id = q.Id;
Title = q.Title;
})
.AsNoTracking()
.OrderByDescending(p => p.Id);
var model = await PagingList.CreateAsync(MyNews, 10, PageIndex);
model.Action = "EditNews";
return View(model);

You pass a List<T> Which is not IQueryable But IEnumerable.
Pass the query result directly:
var MyNews = _context.News.Select(news => new ListNews
{
Id = news.Id,
Title = news.Title,
}).AsNoTracking().OrderByDescending(p => p.Id);
var model = await PagingList.CreateAsync(MyNews, 10, PageIndex);
model.Action = "EditNews";
return View(model);

Related

LINQ to Entities does not recognize the method 'StaticMethod' method

I have a code like this:
using (var ws = new WebService())
using (var db = new EntityFrameworkModel())
{
var originalFolders = ws.GetFolders();
foo.folders = originalFolders.Select(c => new FolderType()
{
Id = c.Description,
Items = ws.ListDocs(c.Id)
.Select((d, i) =>
new DocType()
{
Id = StaticMethod(d, c),
Order = i,
SomeValue = db.docs.Single(doc => doc.Id == StaticMethod(d, c)).SomeValue
}
).ToArray()
}).ToArray();
}
But I get a "LINQ to Entities does not recognize the method 'StaticMethod' method, and this method cannot be translated into a store expression" exception. Does exist any way to pass a static value as a parameter? Something like this:
using (var ws = new WebService())
using (var db = new EntityFrameworkModel())
{
var originalFolders = ws.GetFolders();
foo.folders = originalFolders.Select(c => new FolderType()
{
Id = c.Description,
Items = ws.ListDocs(c.Id)
.Select((d, i, string myValue = StaticMethod(d, c)) =>
new DocType()
{
Id = myValue,
Order = i,
SomeValue = db.docs.Single(doc => doc.Id == myValue).SomeValue
}
).ToArray()
}).ToArray();
}
I can't modify DocType class constructor. Does exist any way?
Usually this is a matter of making sure you don't inline functions in linq-to-SQL expressions that can't be turned into valid SQL.
Try this:
using (var ws = new WebService())
using (var db = new EntityFrameworkModel())
{
var originalFolders = ws.GetFolders();
foo.folders = originalFolders.Select(c => new FolderType()
{
Id = c.Description,
Items = ws.ListDocs(c.Id)
.Select((d, i) =>
{
var id = StaticMethod(d, c);
return new DocType()
{
Id = id,
Order = i,
SomeValue = db.docs.Single(doc => doc.Id == id).SomeValue
};
}).ToArray()
}).ToArray();
}

Create objects into model foreach query

I have a simple model like:
public class StatisticsModel
{
public Guid TaskId { get; set; }
public string Name { get; set; }
public int Time {get; set; }
}
Now I want to add to that model each register of foreach clause like:
StatisticsModel model = new StatisticsModel();
foreach(var i in tasks)
{
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
model.TaskId = i.TaskId;
model.Name = i.Name;
model.Time = test
}
var final2 = model;
So as you can see I assign TaskId, Name and Time to model, but when foreach finish it only add last register to model. How can I create one object foreach task(in my case) in model? I try something like model.Add()but add method donesn't exists in my model. What am I doing wrong? Regards
You're close, you just need a list of models:
List<StatisticsModel> models = new List<StatisticsModel>();
foreach(var i in tasks)
{
StaticsModel model = new StatisticsModel();
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
model.TaskId = i.TaskId;
model.Name = i.Name;
model.Time = test;
models.Add(model);
}
You can't add multiple attributes to a single thing: you must have multiple StatisticsModel objects for this.
For example, you could use a List<StatisticsModel>:
var models = List<StatisticsModel>();
foreach(var i in tasks) {
StatisticsModel model = new StatisticsModel();
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
model.TaskId = i.TaskId;
model.Name = i.Name;
model.Time = test;
models.Add(model);
}
If you prefer LINQ-style queries, you could eliminate the loop altogether:
var models = tasks.Select(i => {
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
return new StatisticsModel {
TaskId = i.TaskId
, Name = i.Name
, Time = test
};
}).ToList();
Sounds like you need a List<StatisticsModel> at the top, that way you can add to it in your foreach:
List<StatisticsModel> models = new List<StatisticsModel>();
foreach(...)
{
...
StatisticsModel model = new StatisticsModel();
// Assign props
models.Add(model);
}
Or even better; since you are actually just transforming the task collection, just use a select:
List<StatisticsModel> models = tasks.Select(task => {
//The foreach contents
StatisticsModel model = new StatisticsModel();
// Assign props
return model;
}).ToList(); //ToList not necessary; eager enumeration is not ideal most of the time but included since you seem to want a list
Each iteration of your foreach loop overwrites the model. Store it in a List:
List<StatisticsModel> allModels = new List<StatisticsModel>();
foreach(var i in tasks)
{
StatisticsModel model = new StatisticsModel();
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
model.TaskId = i.TaskId;
model.Name = i.Name;
model.Time = test
allModels.Add(model);
}
var final2 = allModels;
you need to create a list (or some other collection) to get a list of the models. Here's the code below
List<StatisticsModel> models = new List<StatisticsModel>();
foreach(var i in tasks)
{
var parameters = ToDataTable(tasks.Select(x => new { i.TaskId, i.Name }).ToList());
var timeOfTasks = db.ExeSQLParamTable("usp_Get_WorkedProyectTime", parameters, "#ProjectTimeWorkedTableType");
var test = (from DataRow dr in timeOfTasks.Rows select (int)dr["TaskName"]).FirstOrDefault();
StatisticsModel model = new StatisticsModel();
model.TaskId = i.TaskId;
model.Name = i.Name;
model.Time = test
models.Add(model);
}
var final2 = models; //list of model

EF .Net Core Enumerable.Concat not working

Below is my code
var dbClaimLink = this.Context.Set<ClaimLink>();
var claims = await DbSet
.Include(claim => claim.Parent)
.Include(link => link.ParentLinks)
.ToListAsync();
var newClaimLink = await dbClaimLink.ToListAsync();
var processedClaims = claims.Select(x =>
{
var claimLinks = x.ParentLinks;
if (!claimLinks.Any())
{
return x;
}
var hiddenParents = claimLinks.Select(p => claims.Find(t => t.Id == p.ClaimLinkId));
x.HiddenParents = hiddenParents;
return x;
});
foreach (var objClaim in processedClaims)
{
if (objClaim.Children == null)
objClaim.Children = new List<Claim>();
var lst = newClaimLink.Where(k=> k.ClaimLinkId == objClaim.Id).ToList();
if (lst.Any())
{
foreach (var item in lst)
{
IEnumerable<Claim> newChildren = claims.Where(p => p.Id == item.ClaimId);
objClaim.Children.Concat(newChildren);
}
}
}
it always return old children set without concatenate with new children. I want to those old and new children set concatenate in side of foreach loop
the Concat method returns a new collection with both values and does not alter the original.
Concat will return new object - result of concatination, so you need to save it somewhere: var result = objClaim.Children.Concat(newChildren);
Where is lazy operation, it does not execute in place, only after materialization (ToArray, or foreach call): claims.Where(p => p.Id == item.ClaimId).ToArray()

Merge two Lists of same type with diff values and avoid duplicates

I have two lists of same type with different key value pairs,
List1 has "isPermanent = true" and List2 has false value and also
List1 has an extra key "nextVacationDate".
Im trying to do union of these as below but im afraid I will still get the duplicates because of different values. I need to merge both lists in to one list and order by List1 first (Permanent employees first)..is there a better way to do this using LINQ?
public newList1 List1(string abcd)
{
var result = serviceMethod1(abcd);
var newList1 = new List<emp>();
if (result == null) return null;
newList.AddRange(
result.Select(x => new Model
{
firstName = x.FName,
secondName = x.SName,
address = x.Address,
employeeId = x.EmpId,
isPermanent = true,
nextVacationDate =x.VacDt,
salary = x.Bsalary
}));
return newList1;
}
public newList2 List2(string defg)
{
var result = serviceMethod2(defg);
var newList2 = new List<emp>();
if (result == null) return null;
newList.AddRange(
result.Select(x => new Model
{
firstName = x.FName,
secondName = x.SName,
address = x.Address,
employeeId = x.EmpId,
isPermanent = false,
salary = x.Bsalary
}));
return newList2;
}
private List<emp> EmployyeList(List<emp> newList1, List<emp> newList2)
{
var sortedEmpList1 = newList1.OrderBy(i => i.Fname);
var sortedEmpList2 = newList2.OrderBy(i => i.Fname);
List<MeterModel> combinedList = newList1.Union(newList2) as List<emp>;
return combinedList;
}
You can filter the 2nd list to avoid duplicates:
newList1.Union(newList2.Where(emp2 => !newList1.Any(emp1 => emp1.employeeId == emp2.employeeId)))

Not Returning properly

I was trying to get employee list which not already available in another list. but im getting only first element from array list.
ex : if i try EmployeeId = new int[2] {5, 2}; the list excluding only '5'. So please help me correct my below code.
public JsonResult GetEmployees(int[] EmployeeId)
{
var dbs = new dbContext();
if (EmployeeId != null)
{
foreach (var emp in EmployeeId)
{
var EmpList = dbs.Employees.Select(e => new
{
EmployeeId = e.EmployeeId,
Name = e.EmployeeName,
Job = e.Job.JobName,
Currency = e.Currency.CurrencyName,
Amount = e.Amount
}).Where(o => o.EmployeeId != emp);
return Json(EmpList, JsonRequestBehavior.AllowGet);
}
}
return null
}
Try this :
var employeeList = dbs.Employees.
.Where(e => EmployeeId.All(x=> x != e.EmployeeId))
.Select(e => new
{
EmployeeId = e.EmployeeId,
Name = e.EmployeeName,
Job = e.Job.JobName,
Currency = e.Currency.CurrencyName,
Amount = e.Amount
});
return Json(EmpList, JsonRequestBehavior.AllowGet);
}
Have you tried stepping through your code?
Your foreach iterates over your EmployeeId array.
Since you have a return statement in your foreach it exits the function at that point and it only uses the first element of your array.
You need something like this:
public JsonResult GetEmployees(int[] EmployeeId)
{
var dbs = new dbContext();
if (EmployeeId != null)
{
var EmpList = dbs.Employees.Where(EmployeeId.Contains(e.EmployeeId))
.Select(e => new
{
EmployeeId = e.EmployeeId,
Name = e.EmployeeName,
Job = e.Job.JobName,
Currency = e.Currency.CurrencyName,
Amount = e.Amount
}).Where(o => o.EmployeeId != emp);
return Json(EmpList, JsonRequestBehavior.AllowGet);
}
return null;
}

Categories

Resources