public ActionResult Users()
{
var user = _userRepository.Find(x => x.Id == 1).FirstOrDefault();
return View(user);
}
public ActionResult CashAccountInfo(int id)
{
var result = _cashAccountRepository.Find(x => x.Id == id).FirstOrDefault();
return View(result);
}
When i debug Users() i get
where i have AppUser
but when i debug CashAccountInfo(int id)
i get
without AppUser
Find method from Repository
public virtual IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return DbContext.Set<TEntity>().AsExpandable().Where(predicate).ToList();
}
Please help why in one query get entity but in another cannot get
Assuming you are using entity framework, this is a Lazy Loading issue. Maybe add an Include to your calls when using your context.
For example:
context.Include(x => x.AppUser).FirstOrDefault(x => x.Id == id);
If this isn't the case or you're not using entity framework then you need to show the code for your repository methods.
Related
I have this code to get all Meal from the database but considering optimization, i want to only get the entities needed, instead of returning all.
public async Task<IEnumerable<Meal>> GetAllMeal()
{
return await _dbSet.Include(x => x.MealPrices).ToListAsync();
}
The above code will fetch all entities from the database including the ones i don't need.
Is there a way to map my dto at the point of fetching the data from db
I think you're looking for the Where clause. For example, if your Meal model has an integer Id as the primary key you could do this:
public async Task<Meal> GetMealById(int id)
{
return await _dbSet
.Include(x => x.MealPrices)
.Where(y => y.Id == id)
.FirstOrDefault();
}
How would I do to search two or more tables.
In the system I'm doing, I have the Boat, TypeOfBoat, and ClassBoat tables.
My mapping is as follows:
HasRequired(c => c.ClassBoat )
.WithMany(c => c.Boat)
.HasForeignKey(c => c.ClassBoatId);
HasRequired(c => c.TypeOfBoat)
.WithMany(c => c.Boat)
.HasForeignKey(c => c.TypeOfBoatId);
I made a generic repository for searching
public virtual IEnumerable<TEntity> Search(Expression<Func<TEntity, bool>> predicate)
{
return Dbset.Where(predicate);
}
And I use a generic Interface repository to do specific searches for boats, here are some examples below:
public IEnumerable<Boat> GetByActive()
{
return Search(c => c.Active && !c.excluded);
}
public Boat GetByName(string name)
{
return Search(c => c.Name== name).FirstOrDefault();
}
And if I want to fetch the TypeOfBoat and the ClassBoat, which are different tables, but which are related with the Boat table, how would I do?
My idea is to show this data in a table
Here's a SS how my Database is.
Database
Do you mean including related records for boat?
Try if this query gives you the expected result
public Boat GetByName(string name)
{
var boat = DbContext.Boat
.Include(boat => boat.ClassBoat)
.Include(boat => boat.TypeOfBoat)
.FirstOrDefault(boat => boat.Name == name);
return boat;
}
If you want to use generic repository and then extend query you should return IQueryable<T> instead of IEnumerable<T>.
I'm using entity framework core with ASP.NET Core, code first.
In my app I have invoices, with the typical InvoiceHeader -> InvoiceLine relationship. The InvoiceLine entities have a LineAmount field, which I want to sum and display on the InvoiceHeader when displayed as a list (so I can see the invoice total when viewing the list of invoices).
I'm guessing I'll need to add a TotalAmount property to the InvoiceHeader entity, with the annotation [NotMapped]. But how to most efficiently populate it?
At the moment my InvoiceHeaderController.Index() is:
// GET: InvoiceHeaders
public async Task<IActionResult> Index()
{
ApplicationUser appUser = ConstantData.GetApplicationUser(_context, _userManager.GetUserId(User));
var applicationDbContext = _context.InvoiceHeader.Include(i => i.Customer).Include(i => i.CustomerBranch)
.Where(i => i.CustomerID == appUser.CustomerID);
return View(await applicationDbContext.ToListAsync());
}
Can anyone tell me what the most efficient way is to calculate (sum) this TotalAmount property?
Thanks.
Selecting sum as separate field you need to create new model class as shown below
public class InvoiceHeaderModel{
public InvoiceHeader invoiceHeader{get;set;}
public decimal TotalAmount {get;set;}
}
and make change in action as
// GET: InvoiceHeaders
public async Task<IActionResult> Index()
{
ApplicationUser appUser = ConstantData.GetApplicationUser(_context, _userManager.GetUserId(User));
var applicationDbContext =await _context.InvoiceHeader.Where(i =>i.CustomerID == appUser.CustomerID).ToListAsync();
var data = applicationDbContext.Aggregate( new List<InvoiceHeaderModel>(),(invoiceHeaderModellist, it)=>{ invoiceHeaderModellist.Add(new InvoiceHeaderModel(){ InvoiceHeader =it,TotalAmount = it.InvoiceLine.Sum(t=>t.LineAmount)}); return invoiceHeaderModellist;});
return View(data);
}
In this action i don't think you required to include 'Include(i => i.Customer).Include(i => i.CustomerBranch)' if required you can add before where closure.
I managed to work it out. Saneesh's suggestion was close, but not quite what I wanted.
The code I ended up using is:
// GET: InvoiceHeaders
public async Task<IActionResult> Index()
{
ApplicationUser appUser = ConstantData.GetApplicationUser(_context, _userManager.GetUserId(User));
var applicationDbContext = _context.InvoiceHeader.Include(i => i.Customer).Include(i => i.CustomerBranch)
.Where(i => i.CustomerID == appUser.CustomerID)
.Select(i => new InvoiceListViewModel
{
invoiceHeader = i,
TotalAmount = i.InvoiceLines.Sum(t => t.LineAmount)
});
return View(await applicationDbContext.ToListAsync());
}
Thanks for your help Saneesh.
Assuming that AccountSet returns an IQueryable<Account>, how can I convert this early binding:
XrmServiceContext _xrmServiceContext;
var result = _xrmServiceContext.AccountSet.FirstOrDefault(x => x.Id == locationGuid);
Into something that is more reusable like:
_xrmServiceContext.Where(Set == "Account").FirstOrDefault(x => x.Id == locationGuid);
AccountSet is defined as:
public System.Linq.IQueryable<Xrm.Account> AccountSet
{
get
{
return this.CreateQuery<Xrm.Account>();
}
}
How do I generalize this to be reusable for any IQueryable member of XrmServiceContext ?
As long as the Id is the primary key you can use that in conjunction with find to make a generic call
public T Get<T>(object[] Id)
where T : class
{
return _xrmServiceContext.Set<T>().Find(Id )
}
if your looking for an IQueryable that may be a bit harder but you can find out how to do that off of a previous question I asked:
Entity Framework Filter By PrimaryKey
Courtesy of this post, I've found the following solution:
private static T EntityGet<T>(Guid id)
where T : Entity
{
T item =
(
from query in Context.CreateQuery<T>()
where query.Id == id
select query
).Single();
return item;
}
If I have the following how to do I cast the result of the lambda expression back to the Customer type from IEnumerable<Customer> without having to iterate over it.
public class Customer : CustomerModel
{
public List<Customer> CustomerList {get;set;}
public Customer GetCustomerFromListById(long id)
{
return CustomerList.Select(c => c).Where(i => i.Id == id);
}
}
Use .Single(), also Select is redundant:
return CustomerList.Single(i => i.Id == id);
As mentioned in the comments that way you get an exception if it doesn't contain the needed key, which should be the expected behavior.
Use FirstOrDefault().
return CustomerList.Select(c => c).Where(i => i.Id == id).FirstOrDefault();