I implement the join query for join two tables. How to return those values.
public List<cartItem> getcartItem(int userId)
{
var data = (from c in _context.cartItems join p in _context.Products
on c.productId equals p.ProId
where c.userId == userId && c.status==false select new {
proName=p.ProductName,
qty=c.quantity,
proImg=p.ImageUrl,
uPricce=p.price
}).ToList();
return data;
}
Assuming these are the properties of a cartItem obj, you just need to assign the select statement to match the return type and new up a cartItem.
...select new cartItem
{
proName = p.ProductName,
qty = c.quantity,
proImg = p.ImageUrl,
uPricce = p.price
}).ToList();
Related
I have four tables that are passed to the page in the context. Each of the 4 tables are connected by an Id column. I would like to display a page with a table that combines columns from each of the 4 tables. I would also like to sort or search data and display the results based on 1 or all tables (for example, if table 2 contains the column "Name", then the search results should show only rows that match that name)
public IList<AllTables> AllTableData {get;set;}
public async Task OnGetAsync(
string sortOrder,
string queryFilter,
string searchString)
{
//setting sort and search Params
//......
IQueryable<Table1> table1= _context.Table1.Select(f => f);
IQueryable<Table2> table2= _context.Table2.Select(f => f);
IQueryable<Table3> table3= _context.Table3.Select(f => f);
IQueryable<Table4> table4= _context.Table4.Select(f => f);
if (!String.IsNullOrEmpty(searchString))
{
// e.g. table1= table1.Where(s => s.Id.ToString() == searchString);
}
//Example for sorting
switch (sortOrder)
{
case "Id":
table1= table1.OrderBy(s => s.Id);
break;
case "Name":
table2= table2.OrderBy(s => s.Id);
break;
}
//How do I combine all four tables
AllTableData = await (Join Tables 1-4).AsNoTracking().ToListAsync();
}
I have tried to create a new class such as follows
public Class AllTables
{
public Table1 Table1{get;set;}
public Table2 Table2{get;set;}
public Table3 Table3{get;set;}
public Table4 Table4{get;set;}
}
And then combining the data like this
AllTableData= await table1
.Select(f=>new AllTables(
f,
table2.Where(g => g.Id== f.Id).FirstOrDefault(),
table3.Where(h => h.Id== f.Id).FirstOrDefault(),
table4.Where(i => i.Id== f.Id).FirstOrDefault(),
)).AsNoTracking().ToListAsync();
This gave me full table data, but when I tried to sort based on table2.Name, the sorting did not work.
You can do that in the following way:
IQueryable<Table1> table1 = _context.Table1;
IQueryable<Table2> table2 = _context.Table2;
IQueryable<Table3> table3 = _context.Table3;
IQueryable<Table4> table4 = _context.Table4;
var query =
from t1 in table1
join t2 in table2 on t1.Id equals t2.Id into g
from t2 in g.DefaultIfEmpty()
join t3 in table3 on t1.Id equals t3.Id into g
from t3 in g.DefaultIfEmpty()
join t4 in table4 on t1.Id equals t4.Id into g
from t4 in g.DefaultIfEmpty()
select new AllTables
{
Table1 = t1,
Table2 = t2,
Table3 = t3,
Table4 = t4
};
if (!String.IsNullOrEmpty(searchString))
{
query = query.Where(s => s.Table1.Id.ToString() == searchString);
}
//Example for sorting
switch (sortOrder)
{
case "Id":
query = query.OrderBy(s => s.Table1.Id);
break;
case "Name":
query = query.OrderBy(s => s.Table2.Name);
break;
}
var AllTableData = await query.AsNoTracking().ToListAsync();
I have this in my server to fetch data from a database:
[HttpPost]
[Route("api/getaddress")]
public IQueryable<PreAddress> GetAddress()
{
var httpRequest = HttpContext.Current.Request;
var id = httpRequest["personId"];
int personId;
if (!Int32.TryParse(id, out personId)) return null;
using (var db = new ApplicationDbContext())
{
var preAddress = (from pa in db.PersonAndAddresses
join a in db.Addresses on pa.AddressId equals a.AddressId
join b in db.PersonBarangays on a.BarangayCode equals b.BarangayCode
join m in db.PersonMunicipals on a.MunicipalCode equals m.MunicipalCode
join p in db.PersonProvinces on a.ProvinceCode equals p.ProvinceCode
join r in db.PersonRegions on a.RegionCode equals r.RegionCode
where pa.PersonId == personId
select new PreAddress()
{
BarangayCode = b.BarangayName,
AddressId = a.AddressId,
HouseNumber = a.HouseNumber,
MunicipalCode = m.MunicipalName,
ProvinceCode = p.ProvinceName,
RegionCode = r.Region,
StreetName = a.StreetName,
UnitNumber = a.UnitNumber,
VillageSubdivision = a.VillageSubdivision
});
return preAddress;
}
}
This is how I get the data from the client:
service
getAddress() {
const endpoint = this.rootUrl + '/api/getaddress';
const formData: FormData = new FormData();
formData.append('personId', this.genParams.personId);
return this.http.post(endpoint, formData);
}
component
getPersonInformation() {
this.clientService.getPerson(this.genParams.personId)
.subscribe((data: any) => {
console.log(data);
this.person = data;
});
}
Following the server using debugger, I can actually get a value but in my client side. I get the following error:
I need your help. Thank you.
Try updating your code like this:
[HttpPost]
[Route("api/getaddress")]
public PreAddress GetAddress()
{
var httpRequest = HttpContext.Current.Request;
var id = httpRequest["personId"];
int personId;
if (!Int32.TryParse(id, out personId)) return null;
PreAddress preAddress;
using (var db = new ApplicationDbContext())
{
var preAddress = (from pa in db.PersonAndAddresses
join a in db.Addresses on pa.AddressId equals a.AddressId
join b in db.PersonBarangays on a.BarangayCode equals b.BarangayCode
join m in db.PersonMunicipals on a.MunicipalCode equals m.MunicipalCode
join p in db.PersonProvinces on a.ProvinceCode equals p.ProvinceCode
join r in db.PersonRegions on a.RegionCode equals r.RegionCode
where pa.PersonId == personId
select new PreAddress()
{
BarangayCode = b.BarangayName,
AddressId = a.AddressId,
HouseNumber = a.HouseNumber,
MunicipalCode = m.MunicipalName,
ProvinceCode = p.ProvinceName,
RegionCode = r.Region,
StreetName = a.StreetName,
UnitNumber = a.UnitNumber,
VillageSubdivision = a.VillageSubdivision
});
preAddress = preAddress.FirstOrDefault();
}
return preAddress;
}
You need to execute the IQuerable before you return it, in this scenario try with ToList()
[HttpPost]
[Route("api/getaddress")]
public IEnuerable<PreAddress> GetAddress()
{
var httpRequest = HttpContext.Current.Request;
var id = httpRequest["personId"];
int personId;
if (!Int32.TryParse(id, out personId)) return null;
using (var db = new ApplicationDbContext())
{
var preAddress = (from pa in db.PersonAndAddresses
join a in db.Addresses on pa.AddressId equals a.AddressId
join b in db.PersonBarangays on a.BarangayCode equals b.BarangayCode
join m in db.PersonMunicipals on a.MunicipalCode equals m.MunicipalCode
join p in db.PersonProvinces on a.ProvinceCode equals p.ProvinceCode
join r in db.PersonRegions on a.RegionCode equals r.RegionCode
where pa.PersonId == personId
select new PreAddress()
{
BarangayCode = b.BarangayName,
AddressId = a.AddressId,
HouseNumber = a.HouseNumber,
MunicipalCode = m.MunicipalName,
ProvinceCode = p.ProvinceName,
RegionCode = r.Region,
StreetName = a.StreetName,
UnitNumber = a.UnitNumber,
VillageSubdivision = a.VillageSubdivision
});
return preAddress.ToList(); //invoke it here
}
}
I am using Entity Framework. I have the following query in which I get data using two tables Application and Employee connected by a foreign key EmployeeID in Application Table. The tables have 1-1 relationship .
Is there a way to simplify the following code and get rid of the DTO Employee1
which is the same as auto generated Employee class
public List<Employee1> GetApplicant(int ApplicationID)
{
var context = new FPSDB_newEntities();
var data = (from a in context.Applications
join e in context.Employees on a.EmployeeID equals e.EmployeeID
where
(
a.ApplicationID == ApplicationID
)
select new Employee1
{
EmployeeID = e.EmployeeID,
SecondEmail = e.SecondEmail,
EmailID = e.EmailID,
Title = e.Title,
Name = e.Name,
Rank = e.Rank,
POBox = e.POBox,
Phone = e.Phone,
JoinDate = e.JoinDate,
Status = e.Status,
DepartmentID = e.DepartmentID.Value,
NameString = e.NameString,
Department = e.Department,
ParentDept = e.ParentDept,
DepartmentAr = e.DepartmentAr,
NameAr = e.NameAr,
NameStringAr = e.NameStringAr,
TitleAr = e.TitleAr
}).ToList();
return data;
}
If you need to return list of Employees, just select e which refers to Employee and don't use Employee1 as a DTO.
public List<Employee> GetApplicant(int ApplicationID)
{
var context = new FPSDB_newEntities();
var data = (from a in context.Applications
join e in context.Employees on a.EmployeeID equals e.EmployeeID
where
(
a.ApplicationID == ApplicationID
)
select e).ToList();
return data;
}
Another way is this, which I would prefer because of readability:
public List<Employee> GetApplicant(int ApplicationID)
{
var context = new FPSDB_newEntities();
var data = context.Applications.Where(p=>p.ApplicationID == ApplicationID).Select(p=>p.Employee).ToList();
return data;
}
If I have a lystId, I want to include the MemberProductLyst object and filter by the LystId.
Any suggestions for the proper way to implement the follow up Lamba code inside of the
if (!string.IsNullOrEmpty(lystId)) {} block below the initial query???
products = (from p in dc.Products
join t in dc.Tags on p.TagId equals t.TagId
join pi in dc.ProductImages on p.ProductId equals pi.ProductId
join i in dc.Images on pi.ImageId equals i.ImageId
where p.IsActive == true
where t.TagId == new Guid(brandId)
orderby p.CreatedOn descending
select new ProductItem
{
productImage = i.FileName,
productId = p.ProductId,
description = p.Description,
name = p.Name,
adImage = t.AdImage
}).Skip(totalItemCount).Take(pageSize);
if (!string.IsNullOrEmpty(lystId))
{
//Include MemberProductLyst table to Filter by lystId if LystId is available
var memberLysts = from mpl in dc.MemberProductLysts
where mpl.LystId == new Guid(lystId)
select new { mpl.LystId, mpl.ProductId };
products = (IQueryable<ProductItem>)products.Join(memberLysts, p => p.productId, mpl => mpl.ProductId, (p, mpl) => new {ProductItem = p, MemberProductLyst = mpl });
}
It largely depends on the intent of your Join, but I suspect this may yield the results you're looking for:
products = products.Where(
p => memberLysts.Any(mpl => mpl.ProductId == p.productId));
var result = (from p in productInQuery
join o in orderInfoQuery on p.refNo equals o.refNo
join x in productQuery on p.productNo equals x.no
join t in productOutQuery on p.no equals t.productInNo into productIn
from t in productIn.DefaultIfEmpty()
//let dateOut = (from m in orderInfoQuery where m.refNo == t.refNo select m.delivered).FirstOrDefault()
orderby o.processDate descending
select new
{
modelNo = x.modelNo,
mfgNo = p.mfgNo,
serialNo = p.serialNo,
poNo = p.poNo,
lbs = p.lbs,
width = p.width,
height = p.height,
depth = p.depth,
qty = p.qty,
dateIn = o.processDate,
dateOut = (DateTime?)(from m in orderInfoQuery where m.refNo == t.refNo select m.processDate).FirstOrDefault()
}).ToArray();
I want to add this result into iTextSharp table cell.
but I don't know how to do,
I tried,
int resultSize = result.Length;
/*
for (int j = 0; j < resultSize; j++)
{
table.AddCell(result[j]);
}
*/
foreach (string[] test in result) //Error : Unable to cast object of type
{
int testSize = test.Length;
for (int j = 0; j < testSize; j++)
{
table.AddCell(test[j]);
}
}
but I lost way :(
anybody knows, please advice me~
[EDIT]
int resultSize = result.Length; //192
test does have a fields...
[EDIT 2]
Actually the result be returned from Model.
PJ.WebUI.Models Reports Class
public class Reports
{
public Array GetTransaction(){
OrdersRepository ordersRepository = new OrdersRepository();
var productInQuery = ordersRepository.ProductIn;
var productOutQuery = ordersRepository.ProductOut;
var productQuery = ordersRepository.Product;
var orderInfoQuery = ordersRepository.OrderInfo;
var result = (from p in productInQuery
join o in orderInfoQuery on p.refNo equals o.refNo
join x in productQuery on p.productNo equals x.no
join t in productOutQuery on p.no equals t.productInNo into productIn
from t in productIn.DefaultIfEmpty()
//let dateOut = (from m in orderInfoQuery where m.refNo == t.refNo select m.delivered).FirstOrDefault()
orderby o.processDate descending
select new
{
modelNo = x.modelNo,
mfgNo = p.mfgNo,
serialNo = p.serialNo,
poNo = p.poNo,
lbs = p.lbs,
width = p.width,
height = p.height,
depth = p.depth,
qty = p.qty,
dateIn = o.processDate,
dateOut = (DateTime?)(from m in orderInfoQuery where m.refNo == t.refNo select m.processDate).FirstOrDefault()
}).ToArray();
return result;
}
}
And in controller call the method to get the result.
Reports reposrts = new Reports();
var result = reposrts.GetTransaction();
..
foreach (var test in result)
{
table.AddCell(test.modelNo);
}
Then
Error 1 'object' does not contain a definition for 'modelNo' and no extension method 'modelNo' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
So,
I move the model method into controller method (put all together in same method) and run. then it works!.
but the result be used in the other controller too. so I want to keep the result in Model class to reuse.
I want to know why it does not work if the result query is not in same method.
could you help me a little more please?
Thank you very much!
'result' will be an array of the anonymous type you selected to, not an array of string arrays, which is why you are getting an error in the foreach loop.
Your loop should probably look more like the following:
foreach (var test in result)
{
table.AddCell(test.modelNo);
table.AddCell(test.mfgNo);
table.AddCell(test.serialNo);
// etc
}
#Edit 2:
Because the result of GetTransaction() is 'Array', the calling method has no idea what the type is, it just sees it as an array of objects, and, because it is an anonymous type, you can't (reasonably) cast it back to the expected type.
I think your best bet in this case would be to make a new class which has the properties you want to return, e.g.:
public class Transaction
{
public string ModelNo { get; set; }
public string MfgNo { get; set; }
public string SerialNo { get; set; }
// etc. - but with the correct types for the properties
}
Then change the linq query to select into this type, instead of the anonymous type, e.g.:
...
orderby o.processDate descending
select new Transaction
{
ModelNo = x.modelNo,
MfgNo = p.mfgNo,
SerialNo = p.serialNo,
// etc.
...
And change the return type of GetTransaction() from Array to Transaction[].
It's not clear what you are trying to do but I believe you are casting each element of your result as a string incorrectly.
Try this:
foreach (var test in result)
You will probably need to tweak your inner code since test isn't an array, but that should get you past your current error.