My code returns userid, categoryid, locationid instead of the names to my list view.
I want to return names instead of id
//This is the get method in the service
public async Task<IEnumerable<JobViewModel>> GetAllJobsAsync()
{
var jobs = _appDbContext.Jobs
.Include(j => j.Category)
.Include(j => j.Location)
.Include(j => j.User)
.ToList();
return jobs.Select(job => new JobViewModel(job));
}
//Get method in the controller
public async Task<IActionResult> ListOfJobs()
{
var list = await _jobService.GetAllJobsAsync();
return Ok(list);
}
//This is the JobViewModel
public JobViewModel(JobClass job)
{
JobId = job.JobId;
JobTitle = job.JobTitle;
Description = job.Description;
Requirement = job.Requirement;
Experience = job.Experience;
Salary = job.Salary;
DatePosted = job.DatePosted;
Deadline = job.Deadline;
UserId = job.Id;
CategoryId = job.CategoryId;
LocationId = job.LocationId;
}
public Guid JobId { get; set; }
public string JobTitle { get; set; }
public string Description { get; set; }
public string Requirement { get; set; }
public string Experience { get; set; }
public int Salary { get; set; }
public DateTime DatePosted { get; set; }
public DateTime Deadline { get; set; }
public Guid UserId { get; set; }
public int LocationId { get; set; }
public int CategoryId { get; set; }
public IEnumerable<CategoryViewModel> Categories { get; set; }
public IEnumerable<LocationViewModel> Locations { get; set; }
}
Related
I have a User class
public partial class User
{
public int Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<Blog> Blogs { get; set; }
}
and this is my Blog class
public partial class Blog
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int? PostedBy { get; set; }
public virtual User { get; set; }
public virtual ICollection<BlogImage> BlogImages { get; set; }
}
and my Image class
public partial class BlogImage
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Blog Blog { get; set; }
}
I need to select from Blog with image Name and UserName
I've created this query but I don't now how to join the User class:
var blog = _context.Blog.Include(x => x.BlogImage).Include(a => a.BlogImage).ToListAsync();
Try -
var blog = await _context.Blog
.Select(p => new
{
Id = p.Id,
Title = p.Title,
Content = p.Content,
PostedBy = p.PostedBy,
UserName = p.User.UserName,
ImageNames = p.BlogImages.Select(x => x.Name).ToList()
})
.ToListAsync();
You can also create a DTO type to hold the result you are expecting -
public class BlogDTO
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int? PostedBy { get; set; }
public string UserName { get; set; }
public List<string> ImageNames { get; set; }
}
and then query like -
BlogDTO blogDTO = await _context.Blog
.Select(p => new BlogDTO
{
Id = p.Id,
Title = p.Title,
Content = p.Content,
PostedBy = p.PostedBy,
UserName = p.User.UserName,
ImageNames = p.BlogImages.Select(x => x.Name).ToList()
})
.ToListAsync();
I have two table like this -
public class Job
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime AddedTime { get; set; } = DateTime.Now;
public DateTime LastEdit { get; set; } = DateTime.Now;
public string Explanation { get; set; }
public string PhotoString { get; set; }
public bool isActive { get; set; } = true;
public int CompanyId { get; set; }
public Company Company { get; set; }
}
and company -
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Explanation { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public string PhotoString { get; set; }
public bool isActive { get; set; } = true;
public int AppUserId { get; set; }
public AppUser AppUser { get; set; }
public List<Job> Jobs { get; set; }
}
I only want to get AppUserId from Company and all Jobs from every Company. I tried this and it gave me error.
using var context = new SocialWorldDbContext();
return await context.Jobs.Where(I => I.isActive == true && I.Company.isActive).Include(I=>I.Company.AppUserId).ToListAsync();
So my question is there any way I can get this data from parent?
Include adds whole entities to the output. To add just one property use Select, something like
context.Jobs
.Where(I => I.isActive == true && I.Company.isActive)
.Select(e => new {Job=e, CompanyAppUserId = e.Company.AppUserId})
.ToListAsync();
My app deals with saving orders received from an external system. The order contains child items like line items, address, fulfillments, refunds > refund items etc.
Currently, I use an ugly looking code to detect what has changed in each entity by its External Id. Can someone recommend me a better way? :)
Following is a simplified entity model of Order
public class Order
{
public long Id { get; set; }
public string ExternalOrderId { get; set; }
public List<LineItem> LineItems { get; set; }
public List<Fulfillment> Fulfillments { get; set; }
public ShippingAddress ShippingAddress { get; set; }
public List<Refund> Refunds { get; set; }
public string FinancialStatus { get; set; }
public string FulfillmentStatus { get; set; }
}
public class LineItem
{
public long Id { get; set; }
public string ExternalLineItemId { get; set; }
public string SKU { get; set; }
public int Quantity { get; set; }
public long OrderId { get; set; }
}
public class Fulfillment
{
public long Id { get; set; }
public string ExternalFulfillmentId { get; set; }
public string Status { get; set; }
public string TrackingUrl { get; set; }
public long OrderId { get; set; }
}
public class ShippingAddress
{
public long Id { get; set; }
public string ExternalShippingAddressrId { get; set; }
public string Addres { get; set; }
public long OrderId { get; set; }
}
public class Refund
{
public long Id { get; set; }
public string ExternalRefundId { get; set; }
public List<RefundedItem> LineItems { get; set; }
public string CancelledReason { get; set; }
public long OrderId { get; set; }
}
public class RefundedItem
{
public long Id { get; set; }
public string ExternalRefundedItemId { get; set; }
public string SKU { get; set; }
public int Quantity { get; set; }
}
My sample code:
private async Task ManageFulfillments(long orderId, Order order)
{
if (order.Fulfillments == null || !order.Fulfillments.Any()) return;
var newFulfillmentIds = order.Fulfillments.Select(c => c.ExternalFulfillmentId).ToList();
var dbFulfillments = await _fulfillmentRepository.GetAll().IgnoreQueryFilters()
.Where(c => c.OrderId == orderId)
.Select(c => new { c.Id, c.ExternalFulfillmentId }).ToListAsync();
var dbFulfillmentIds = dbFulfillments.Select(c => c.ExternalFulfillmentId).ToList();
// Delete Fulfillments that are not present in new Fulfillments list
var deletedFulfillments = dbFulfillmentIds.Except(newFulfillmentIds).ToList();
if (deletedFulfillments.Any())
{
await _fulfillmentRepository.DeleteAsync(c =>
deletedFulfillments.Contains(c.ExternalFulfillmentId) && c.ExternalOrderId == orderId);
}
// Update existing Fulfillments ids
order.Fulfillments
.Where(c => dbFulfillmentIds.Contains(c.ExternalFulfillmentId))
.ToList()
.ForEach(async c =>
{
c.Id = dbFulfillments.Where(p => p.ExternalFulfillmentId == c.ExternalFulfillmentId)
.Select(p => p.Id).FirstOrDefault();
await _fulfillmentRepository.UpdateAsync(c);
});
// New Fulfillments will automatically be added by EF
}
I have similar code in place to update other entites as well and I'm not proud of it!
How to calculate account receivable using LINQ.
I have tried this but stuck here.
I have done this in SQL but I want this in LINQ so I can use it in my MVC project.
var sale = saleslist.GroupBy(s => s.BuyerId).Select(s => s.Sum(u => u.Amount)).ToList();
var receipt = receiptslist.GroupBy(r => r.StakeHolderId).Select(t => t.Sum(u => u.Amount)).ToList();
List<AccountReceivablesVM> res = db.StakeHolders
.Where(r=>r.StakeHolderTypeId == "0b85a69e-55f2-4142-a49d-98e22aa7ca10")
.Select(rvm => new AccountReceivablesVM
{
CompanyName = rvm.CompanyName,
Receivables = //don't know what to do here
}).ToList();
Models:
public class StakeHolder
{
public string StakeHolderId { get; set; }
public string CompanyName { get; set; }
public string Address { get; set; }
public string Contact { get; set; }
public string StakeHolderTypeId { get; set; }
}
public class Sale
{
public string SaleId { get; set; }
public string RefNo { get; set; }
public DateTime Date { get; set; }
public string BuyerId { get; set; }
public string Description { get; set; }
public Nullable<double> Amount { get; set; }
}
public class PaymentsAndReceipt
{
public string PaymentAndReceiptId { get; set; }
public Nullable<int> VoucherNo { get; set; }
public DateTime Date { get; set; }
public string StakeHolderId { get; set; }
public string Description { get; set; }
public Nullable<double> Amount { get; set; }
}
public class AccountReceivablesVM
{
public string CompanyName { get; set; }
public Nullable<double> Receivables { get; set; }
}
Expected Result:
You can join first with stakeholderId and then sum the amount and then group by with company name and stakeholder id, however I write the code in Linq. I have considered the stakeholderid as the primary key of your table just because you have not mentioned the schema of stakeholder so.
var result = from s in db.StakeHolders
join pr in db.PaymentsAndReceipt on s.StakeHolderId equals pr.StakeHolderId
where StakeHolderTypeId == "0b85a69e-55f2-4142-a49d-98e22aa7ca10"
group s by new { s.StakeHolderId,s.CompanyName} into p
select new
{
StakeHolderId= p.Key.StakeHolderId,
CompanyName= p.Key.CompanyName,
Receivables = string.Format("{0:C}", p.Sum(y => y.Amount))
};
I want to get sorted products(table products) by 'value'(table Product Parameters) according to "ParamertomId"(table Parameters) from my model.
How to sort related data correctly?
These are my model classes:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Number { get; set; }
public double Amount { get; set; }
public double PrimeCostEUR { get; set; }
[ForeignKey("ProductTypeId")]
public int ProductTypeId { get; set; }
public virtual ProductType ProductType { get; set; }
public ICollection<ProductParameter> ProductParameters { get; set; } = new List<ProductParameter>();
}
public class ProductType //: BaseObject
{
public int Id { get; set; }
public string NameType { get; set; }
public ICollection<Parameter> Parameters { get; set; } = new List<Parameter>();
public ICollection<Product> Products { get; set; } = new List<Product>();
}
public class Parameter
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("ProductType")]
public int ProductTypeId { get; set; }
public virtual ProductType ProductType { get; set; }
public ICollection<ProductParameter> ProductParameters { get; set; } = new List<ProductParameter>();
}
public class ProductParameter
{
public int Id { get; set; }
public int ProductId { get; set; }
public virtual Product Product { get; set; }
public int ParameterId { get; set; }
public virtual Parameter Parameter { get; set; }
public string Value { get; set; }
}
These are my DTO classes needed to display the data I need.:
public class ProductDTO{
public int ProductId { get; set; }
public string Number { get; set; }
public double Amount { get; set; }
public double PrimeCostEUR { get; set; }
public int ProductTypeId { get; set; }
public string NameType { get; set; }
public ICollection<ParameterDTO> Parameters { get; set; } = new
List<ParameterDTO>();}
public class ParameterDTO {
public int Id { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
I receive related data from three table. This my method GetSortedProducts:
public async Task<IEnumerable<ProductDTO>> GetProducts(int id)
{
var typeParams = _context.Parameters
.Where(t => t.ProductTypeId == id)
.ToList();
var products = _context.Products
.Include(t => t.ProductParameters)
.Where(t => t.ProductTypeId == id)
.ToList();
var items = new List<ProductDTO>();
foreach (var product in products)
{
var productDTO = new ProductDTO()
{
ProductId = product.Id,
Number = product.Number,
Amount = product.Amount,
PrimeCostEUR = product.PrimeCostEUR,
ProductTypeId = product.ProductTypeId
};
foreach (var typeParam in typeParams)
{
var paramDTO = new ParameterDTO();
var value = product.ProductParameters.FirstOrDefault(t => t.ParameterId == typeParam.Id);
if (value != null)
{
paramDTO.Id = value.Id;
paramDTO.Value = value.Value;
}
paramDTO.ParameterId = typeParam.Id;
paramDTO.Name = typeParam.Name;
productDTO.Parameters.Add(paramDTO);
}
// sort products by value
productDTO.Parameters.Where(y => y.ParameterId == 4)
.OrderBy(t => t.Value).ToList();
items.Add(productDTO);
}
return items;
}
It doesn't work because LINQ never affects the original collection, so this doesn't do anything at all:
productDTO.Parameters
.Where(y => y.ParameterId == 4)
.OrderBy(t => t.Value)
.ToList();
Overall, anyway, that code is not even close to good code. Don't create Product (and others) objects just to convert them to their DTO version. Use Entity Framework properly:
var products = await _context.Products
.Where(prod => prod.ProductTypeId == id)
.Select(prod => new ProductDTO
{
ProductId = prod.ProductId,
// rest of properties...
// now get the parameters
Parameters = prod.Parameters
// assuming you want to order by value, the question isn't very clear
.OrderBy(par => par.Value)
.Select(par => new ParameterDTO
{
Id = par.Id,
// etc
})
.ToList()
})
.ToListAsync();
Compare that single database query to the multiple calls that the question's code is doing when the data is already in memory.