I've been struggling for days now trying to implement jQuery Bootgrid with my ASP.Net application. So far this is what I have: (Order By Functionality isn't working yet, I'll tackle that later)
public JsonResult IndexJson(RequestData model)
{
var result = (from x in db.ContactSet
select new
{
x.AccountId,
x.FirstName,
x.LastName,
x.FullName,
x.JobTitle,
x.ParentCustomerId,
x.EMailAddress1,
x.Telephone1,
x.MobilePhone,
x.Fax,
x.GenderCode,
x.BirthDate
}); //? Gets all rows
result = (from x in result
where x.FirstName.Contains(model.searchPhrase)
|| x.LastName.Contains(model.searchPhrase)
select x); //? Search Filter
var totalRows = result.Count(); //? Sets totalRows (for ResponseData)
if (model.rowCount == -1)
model.rowCount = totalRows; //? In case View All Rows is selected by Bootgrid (for ResponseData)
// TODO: Add Order By functionality
var tResult = new ResponseData<object>()
{
current = model.current,
rowCount = model.rowCount,
rows = result.ToList(),
total = totalRows
}; //? Builds Json Response
return Json(tResult, JsonRequestBehavior.AllowGet);
}
The problem with this code is I need to count the total number of records after the search functionality and I'm just not that skilled at using the LINQ Queries properly.
By the time I get to var totalRows = result.Count(); I get the following error:
System.NotSupportedException: 'The method 'Where' cannot follow the method 'Select' or is not supported. Try writing the query in terms of supported methods or call the 'AsEnumerable' or 'ToList' method before calling unsupported methods.'
Any idea what's wrong here?
I have been using bootgrid in difference situations, including implementing server-side paging and sorting asc, desc without any problem.
Try this:
//Let's assume this is your model....
public class RequestData
{
public int RowCount { get; set; }
public int Current { get; set; }
public string Search { get; set; }
public string SortBy { get; set; }
public string SortDirection { get; set; }
public int TotalItems { get; set; }
}
1.If you are not selecting all the columns of your DB table, create a DTO that will map your selected columns. Otherwise skip this part and replace anywhere you see ContactSetDTO with ContactSet
public class ContactSetDTO
{
public string AccountId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
public string JobTitle { get; set; }
public string ParentCustomerId { get; set; }
public string EMailAddress1 { get; set; }
public string Telephone1 { get; set; }
public string MobilePhone { get; set; }
public string Fax { get; set; }
public string GenderCode { get; set; }
public DateTime BirthDate { get; set; }
}
2.Assuming you are using SQL Server, you could use the following method to retrieve the count:
public int getContactSetCount(string searchPhrase)
{
int ret = 0;
try
{
string query = string.Empty;
if (!string.IsNullOrWhiteSpace(searchPhrase))
{
// ********* Assuming your db table is also called ContactSet **********************
query = #"SELECT COUNT(*) FROM ContactSet s WHERE s.FirstName LIKE '%' + #p0 + '%' OR s.LastName LIKE '%' + #p0 + '%')";
ret = db.Database.SqlQuery<int>(query, new System.Data.SqlClient.SqlParameter(parameterName: "#p0", value: searchPhrase)).FirstOrDefault();
}
else
{
ret = db.ContactSet.Count();
}
}
catch (Exception)
{
throw;
}
return ret;
}
3.And finally, your method would look like this:
public JsonResult IndexJson(RequestData model)
{
var searchPhrase = model.Search;
if (!string.IsNullOrWhiteSpace(searchPhrase))
{
//Notice that the select columns match the ContactSetDTO properties
string query = #"SELECT TOP " + model.RowCount + " s.AccountId, s.FirstName, s.LastName, s.FullName, s.JobTitle, s.ParentCustomerId, s.EmailAddress1, s.Telephone1, s.MobilePhone, s.Fax, s.GenderCode, s.BirthDate FROM ContactSet s WHERE s.FirstName LIKE '%' + #p0 + '%' OR s.LastName LIKE '%' + #p0 + '%')";
//Then, this should return a list of ContactSetDTO for you
var result = db.Database.SqlQuery<ContactSetDTO>(query, new System.Data.SqlClient.SqlParameter(parameterName: "#p0", value: searchPhrase)).ToList();
var totalRows = getContactSetCount(searchPhrase);
var tResult = new { rows = result, rowCount = model.RowCount, total = totalRows, current = model.Current, searchPhrase = model.Search }
};
return Json(tResult, JsonRequestBehavior.AllowGet);
}
I hope the above will help.
Related
I'm trying to query one to many on dapper but for some reason I only get 1 value back from my joined table even though I should be getting multiple as from my query
Can someone tell me what I did wrong?
I tried doing what was mentioned in the following post answer Mapping one to many with Dapper
My code:
public class MonsterDatabase
{
public int Id { get; set; }
public int MonsterId { get; set; }
public string Name { get; set; }
public List<MonsterLocationDatabase> Location { get; set; }
}
public class MonsterLocationDatabase
{
public int Id { get; set; }
public int FkMonsterId { get; set; }
public string Map { get; set; }
public int Frequency { get; set; }
public string MapImage { get; set; }
public DateTime? DeathTime { get; set; }
public DateTime? RespawnTime { get; set; }
}
public static MonsterDatabase GetMonster(Monster monster)
{
using (var connection = new SqlConnection(config["appsettings:RagnaDatabase"]))
{
var Monster = connection.Query<MonsterDatabase, MonsterLocationDatabase, MonsterDatabase>(
"select top 1 Monster.*, SplitMonster = '', MonsterLocation.*" +
" from Monster" +
" join MonsterLocation" +
" on Monster.Id = MonsterLocation.FkMonsterId",
(Monster, Location) =>
{
Monster.Location = new List<MonsterLocationDatabase>();
Monster.Location.Add(Location);
return Monster;
}, splitOn: "SplitMonster"
).FirstOrDefault();
return Monster;
}
}
I was able to fix the issue by following the one to many dapper documentation on
https://dapper-tutorial.net/result-multi-mapping
public static MonsterDatabase GetMonster()
{
using (var connection = new SqlConnection(config["appsettings:RagnaDatabase"]))
{
var monsterDictionary = new Dictionary<int, MonsterDatabase>();
var Monster = connection.Query<MonsterDatabase, MonsterLocationDatabase, MonsterDatabase>(
"select top 10 Monster.*, SplitMonster = '', MonsterLocation.*" +
" from Monster" +
" left join MonsterLocation" +
" on Monster.Id = MonsterLocation.FkMonsterId",
(Monster, Location) =>
{
MonsterDatabase monsterEntry;
if(!monsterDictionary.TryGetValue(Monster.Id, out monsterEntry))
{
monsterEntry = Monster;
monsterEntry.Location = new List<MonsterLocationDatabase>();
monsterDictionary.Add(monsterEntry.Id, monsterEntry);
}
monsterEntry.Location.Add(Location);
return monsterEntry;
}, splitOn: "SplitMonster"
).Distinct().FirstOrDefault();
return Monster;
}
}
I'm using EF 6.2 with SQL. Suppose I have these DTO classes:
private class ParentModel
{
public string FullName { get; set; }
public IEnumerable<ChildModel> Children { get; set; }
}
private class ChildModel
{
public string FullName { get; set; }
public string SpiritAnimalDescription { get; set; }
}
ParentModel is derived from an entity class Parent.
ChildModel is from Child, which has a relationship with another entity class SpiritAnimal. Note that I changed it in the .EDMX to Children.
As you can infer, SpiritAnimal has a Description field which I'm trying to retrieve into the ChildModel field, SpiritAnimalDescription.
Naturally, a Parent has a collection of Child, which in turn has one SpiritAnimal (by design). Now, I'm trying to obtain a List<ParentModel> with this code, which currently isn't working:
var query = from p in db.Parents
join c in db.Children on p.Id equals c.Parent_Id
join sa in db.SpiritAnimals on c.SpiritAnimal_Id equals sa.Id
select new ParentModel
{
FullName = p.LastName + ", " + p.FirstName
Children = c.Select(a => new ChildModel // <-- Error here :(
{
FullName = a.FirstName + " " + a.LastName,
SpiritAnimalDescription = sa.Description
}
};
var list = query.ToList();
How can I solve this, as efficiently as possible? Thanks!
EDIT:
Entity classes look something like this, for brevity:
private class Parent
{
public int Id { get; set; } // PK
public string LastName { get; set; }
public string FirstName { get; set; }
}
private class Child
{
public int Id { get; set; } // PK
public string LastName { get; set; }
public string FirstName { get; set; }
public int Parent_Id { get; set; } // FK
public int SpiritAnimal_Id { get; set; } // FK
}
private class SpiritAnimal
{
public int Id { get; set; } // PK
public string Description { get; set; }
}
Your code cannot be compiled and run, so it is impossible to determine exactly what should be.
I can only assume that it should be something like this:
var query = from p in db.Parents
select new ParentModel
{
FullName = p.LastName + ", " + p.FirstName,
Children = db.Children.Where(c => c.Parent_Id == p.Id)
.Select(c => new ChildModel
{
FullName = c.FirstName + " " + c.LastName,
SpiritAnimalDescription = db.SpiritAnimals
.FirstOrDefault(sa => sa.Id == c.SpiritAnimal_Id).Description
})
};
Note: use the navigation properties.
Should look something like this:
var query = from p in db.Parents
select new ParentModel()
{
FullName = p.LastName + ", " + p.FirstName,
Children = p.Clildren.Select(a => new ChildModel()
{
FullName = a.FirstName + " " + a.LastName,
SpiritAnimalDescription = sa.Description
}).ToList()
};
I have a question about how to find collections of values from one table that match some values from another table.
Here's my code snippet:
public async Task<List<TableB>> GetTableBResults(string vCode, string number)
{
var tableARepo = DependencyResolver.Get<IRepository<DBTableA>>();
var TableBRepo = DependencyResolver.Get<IRepository<DBTableB>>();
var tableAQuery = string.Format("SELECT * FROM DBTableA WHERE Identifier = '{0}'",
number);
List<DBTableA> tableA = await tableARepo.QueryAsync(tableAQuery);
if (tableA != null)
{
//Find all tableB records with info from Identifier
//And then do a distinct on BusinessName and return those results
foreach (var item in DBTableA)
{
var TableBQuery = String.Format("SELECT *" +
"FROM[DBTableB] INNER JOIN DBTableA" +
"ON DBTableB.Code = {0}" +
"AND DBTableB.HouseNo = {1}" +
"AND DBTableB.BusinessName = {2}" +
"AND DBTableB.VCode = {3}",
item.Code, item.HouseNo, item.FirstName, vCode);
List<DBTableB> tableB = await TableBRepo.QueryAsync(TableBQuery);
if (tableBs != null)
{
return tableBs.Select(_ => new TableB
{
BoroCode = _.BoroCode,
Code = _.Code,
HouseNo = _.HouseNo,
Date = _.Date,
BusinessName = _.BusinessName,
}).ToList();
}
else
{
return new List<TableB>();
}
}
}
return new List<TableB>();
}
Here are the entities:
public class DBTableA
{
[PrimaryKey, AutoIncrement]
public int DBTableAKey { get; set; }
[NotNull]
[Indexed]
public Int64 Identifier { get; set; }
[NotNull]
public int Code { get; set; }
[Indexed]
public int? HouseNo { get; set; }
public string FirstName { get; set; }
}
public class DBTableB
{
[PrimaryKey, AutoIncrement]
public int DBTableBKey { get; set; }
[NotNull]
[Indexed]
public string BoroCode { get; set; }
[NotNull]
[Indexed]
public int Code { get; set; }
[NotNull]
[Indexed]
public string HouseNo { get; set; }
[NotNull]
public DateTime Date { get; set; }
[NotNull]
public string BusinessName { get; set; }
[NotNull]
[Indexed]
public string VCode { get; set; }
}
Basically, using Identifier from TableA, I want to get all matches rows from Table A where Identifier is equal to the number passed in. Then, do a compare where select fields from that tableA set match same values in TableB set
but I'm not sure how to set up the logic, I added my attempt above.
I mean I just want to return the values from Table B that matches the parameters I want to check/match in the sql query above if any. How can I improve my code above to make return the correct values?
EDIT:
Here is some mock data:
Identifier: 123 (only in TableA: grab Code, HouseNo, FirstName that have Identifier 123)
Then match those from Table A with values from Table B where the values are the same like the sample values below:
Code = 456
HouseNo = 34
BusinessName = 'Bar, Foo'
VCode = 'E4T' (passed in to method)
Return TableB row(s) that match the above info.
You should just be able to use LINQ to handle this query:
var ans = (from a in tableARepo
where a.Identifier == number
join b in tableBRepo on new { a.Code, HouseNo = a.HouseNo.ToString(), a.FirstName, VCode = vCode } equals new { b.Code, b.HouseNo, FirstName = b.BusinessName, b.VCode }
select b).ToList();
return ans;
I have a form with four text boxes and two comboboxes ...
i am filtering the data and displaying the data in datagrid view depends upon the selection in combobox and text typed in textboxes ..
for that i have written the below code
private void btnRunreports_Click(object sender, EventArgs e)
{
int agefrom = Convert.ToInt32(cbGEFrom.Text);
int ageto = Convert.ToInt32(cbGETo.Text);
DateTime today = DateTime.Today;
DateTime max = today.AddYears(-(agefrom + 1));
DateTime min = today.AddYears(-(ageto));
string maximum = Convert.ToString(max);
string minimum = Convert.ToString(min);
string gender = "";
gender = Classes.reportmembers.ConvertGender(cbGEGendertype.Text);
var mems = Classes.reportmembers
.getallreportmembers(gender,
cbGEMembershiptype.SelectedText,
txtlastname.Text,
txtpostcode.Text,
txtcardnum.Text,
txtreference.Text,
cbGEStatustype.SelectedText,
maximum, minimum);
BindingSource bs = new BindingSource();
bs.DataSource = mems;
dgvReportMembers.DataSource = bs;
}
and this is my class reportmembers:
class ReportMebers
{
public int MemberID { get; set; }
public string Lastname { get; set; }
public string Firstname { get; set; }
public string Postcode { get; set; }
public string Reference { get; set; }
public string CardNum { get; set; }
public string IsBiometric { get; set; }
public string DOB { get; set; }
public string MShipType { get; set; }
public string StatusType { get; set; }
public string EndDate { get; set; }
}
class reportmembers
{
public static List<ReportMebers> getallreportmembers(string gender, string membershiptype, string lastname,
string postcode,string cardnum,string refernce,
string membershipstatustypesa, string maxage, string minage)
{
//CultureInfo provider = CultureInfo.InvariantCulture;
EclipseEntities eclipse = new EclipseEntities();
List<ReportMebers> reporall = new List<ReportMebers>();
var memberreport = from report in eclipse.members
join memtomship in eclipse.membertomships on report.member_Id equals memtomship.member_Id
join mshoption in eclipse.mshipoptions on memtomship.mshipOption_Id equals mshoption.mshipOption_Id
join membershiptypes in eclipse.mshiptypes on mshoption.mshipType_Id equals membershiptypes.mshipType_Id
join membershipstatustypes in eclipse.mshipstatustypes on memtomship.mshipStatusType_Id equals membershipstatustypes.mshipStatusType_Id
where report.member_Lastname.Equals(lastname)
&& report.member_CardNum.Equals(cardnum)
&& report.member_Postcode.Equals(postcode)
&& report.member_Reference.Equals(refernce)
&& report.member_Gender.Equals(gender)
&& membershiptypes.mshipType_Name.Equals(membershiptype)
&& membershipstatustypes.mshipStatusType_Name.Equals(membershipstatustypesa)
&& string.Compare(report.member_Dob,maxage) >= 0
&& string.Compare(report.member_Dob, minage)< 0
select new
{
report.member_Id,
report.member_Lastname,
report.member_Firstname,
report.member_Postcode,
report.member_Reference,
report.member_CardNum,
report.member_IsBiometric,
report.member_Dob,
membershiptypes.mshipType_Name,
membershipstatustypes.mshipStatusType_Name,
memtomship.memberToMship_EndDate
};
try
{
foreach (var membe in memberreport)
{
ReportMebers allmembersrepor = new ReportMebers();
allmembersrepor.MemberID = membe.member_Id;
allmembersrepor.Lastname = membe.member_Lastname;
allmembersrepor.Firstname = membe.member_Firstname;
allmembersrepor.Postcode = membe.member_Postcode;
allmembersrepor.Reference = membe.member_Reference;
allmembersrepor.CardNum = membe.member_CardNum;
allmembersrepor.IsBiometric = membe.member_IsBiometric;
allmembersrepor.DOB = membe.member_Dob;
allmembersrepor.MShipType = membe.mshipType_Name;
allmembersrepor.StatusType = membe.mshipStatusType_Name;
allmembersrepor.EndDate = membe.memberToMship_EndDate;
reporall.Add(allmembersrepor);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return reporall;
}
if i type robin in txtlastname the details will be displayed whoose last name is robin...
i have checked in database there is person with last name robin..
but it does not displayed in datagrid view...
would any guys pls help on this...
Many thanks In advance....
Your problem is, that you are doing an AND comparison over all fields. That means, only entries from the database are returned, that match ALL entered data! If you only enter robin as last name and nothing else, you will get no results, because all the other fields aren't matching. Change your query to include only those fields that are not empty. Something like this:
var query = from report in eclipse.members
join memtomship in eclipse.membertomships on report.member_Id equals memtomship.member_Id
join mshoption in eclipse.mshipoptions on memtomship.mshipOption_Id equals mshoption.mshipOption_Id
join membershiptypes in eclipse.mshiptypes on mshoption.mshipType_Id equals membershiptypes.mshipType_Id
join membershipstatustypes in eclipse.mshipstatustypes on memtomship.mshipStatusType_Id equals membershipstatustypes.mshipStatusType_Id;
if(!string.IsNullOrEmpty(lastname))
query = query.Where(r => r.member_Lastname == lastname);
if(!string.IsNullOrEmptry(cardnum)
query = query.Where(r => r.member_CardNum == cardnum);
// and so on for all parameters
I have this situation:
My ModelView:
public class Subject
{
public int ID { get; set; }
public string Name { get; set; }
public int ProfessorID { get; set; }
public string ProfessorFullName{ get; set; }
public IList<Assistant> Assistants { get; set; }
}
public class Assistant
{
public string AssistantFullName{ get; set; }
}
My query:
var subjects = from subject in Entities.Subjects
from professor in subject.Lecturers
where professor.Professor == true
select new SSVN.ModelView.Subject()
{
ID = subject.ID,
Name= subject.Name,
ProfessorFullName= professor.LastName+ " " + professor.Name,
Assistants= (from subject1 in Entities.Subjects
from assistant in subject1.Lecturers
where assistant.Professor == false
select new SSVN.ModelView.Assistant()
{
AssistantFullName = assistant.LastName+ " " + assistant.Name
}).ToList()
};
And when I call:
subjects.ToList(); I get exception:
LINQ to Entities does not recognize the method
'System.Collections.Generic.List`1[SSVN.ModelView.Assistant] ToList[Assistant]
(System.Collections.Generic.IEnumerable`1[SSVN.ModelView.Assistant])' method, and this
method cannot be translated into a store expression.
You cannot call ToList inside linq-to-entities query. Linq-to-entities query will always project to IEnumerable<T> so if you want IList<T> you must call it in linq-to-objects.
Try this:
var subjects = (from subject in Entities.Subjects
from professor in subject.Lecturers
where professor.Professor == true
select new
{
ID = subject.ID,
Name= subject.Name,
ProfessorFullName= professor.LastName+ " " + professor.Name,
Assistants= (from subject1 in Entities.Subjects
from assistant in subject1.Lecturers
where assistant.Professor == false
select new SSVN.ModelView.Assistant()
{
AssistantFullName = assistant.LastName+ " " + assistant.Name
})
}).AsEnumerable().Select(x => new SSVN.ModelView.Subject
{
ID = x.ID,
Name = x.Name,
ProfessorFullName = X.ProffesorFullName,
Assistants = x.Assistants.ToList()
});
You cannot and should not use a ToList() in an IQueryablle query. Note that this query has to be translated into SQL.