I am using EntityFramework which creates a local database and I would like to perform Join operation to show the Purchases done for each Customer, but I can't see to make it work.
Here is my Customer Model
public class Customer
{
[Key]
public int custId { get; set; }
public string firstName { get; set; }
public string surname { get; set; }
public string addresss { get; set; }
}
Here is my Purchase Model
public class Purchase
{
public int purchaseId { get; set; }
public int custId { get; set; }
public int productId { get; set; }
public double price { get; set; }
public int quantity { get; set; }
public double deliveryFees { get; set; }
public double finalAmount { get; set; }
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime dateOfPurchase { get; set; }
}
I have tried to create a ViewModel which should keep each Model in the class, so that I could perform join and it is shown down below:
public class ViewModel
{
public Customer customer { get; set; }
public Purchase purchase { get; set; }
public List<Customer> customers;
public List<Purchase> purchases;
}
And I have created a Controller for ViewModel to try to
public ActionResult Index()
{
using (db)
{
var cust = (from p in db.PurchaseList
join c in db.Customers on p.custId equals c.custId
select new
{
id = p.custId,
firstName = c.firstName,
surname = c.surname,
total = p.finalAmount.ToString()
}
).ToList();
return View(cust);
}
}
The db variable is the context of the database that I am using.
public Context() : base("name=Context")
{
}
public void CreateDatabase()
{
}
public System.Data.Entity.DbSet<Models.Offer> Offers { get; set; }
public System.Data.Entity.DbSet<Models.Employee> Employees { get; set; }
public System.Data.Entity.DbSet<Models.Customer> Customers { get; set; }
public System.Data.Entity.DbSet<Models.User> Users { get; set; }
public System.Data.Entity.DbSet<Models.Purchase> PurchaseList { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
In my View page I am only doing a foreach to retrieve the data but it is always empty. Do you have any suggestion? Should I use a different approach to the above?
Have you given correct relationships in your dbContext class?
Refer my sample application
(https://github.com/AvanthaSiriwardana/TheProjector-V1.0/blob/master/TheProjector.Domain/Entities/TheProjectorContext.cs)
Related
I working a project and i need use lazyloading i installed package and configure,query working but relationship columns returned null. How to i can use lazyloading?
Installed Microsoft.EntityFrameworkCore.Proxies(version 5.0.7)
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("ConnectionString");
optionsBuilder.UseLazyLoadingProxies(true);
}
}
My Models(I make with DB First)
public partial class Customer
{
public Customer()
{
Orders = new HashSet<Order>();
}
public int CustomerId { get; set; }
public int? CompanyId { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
public string Phone { get; set; }
public string Mail { get; set; }
virtual public Company Company { get; set; }
virtual public ICollection<Order> Orders { get; set; }
}
public partial class Company
{
public Company()
{
Customers = new HashSet<Customer>();
}
public int CompanyId { get; set; }
public string Name { get; set; }
public string TaxNumber { get; set; }
public virtual ICollection<Customer> Customers { get; set; }
}
Used Method:
public List<Customer> GetCustomers()
{
using (dbContext context = new dbContext())
{
return context.Customers.ToList();
}
}
According to the documentation, lazy loading should be implemented in this way
Install Microsoft.EntityFrameworkCore.Abstractions package too and change the implementation:
public partial class Customer
{
private ICollection<Orders> _orders;
public Customer()
{
Orders = new HashSet<Order>();
}
public Customer(ILazyLoader lazyLoader)
{
LazyLoader = lazyLoader;
}
private ILazyLoader LazyLoader { get; set; }
public int CustomerId { get; set; }
public int? CompanyId { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
public string Phone { get; set; }
public string Mail { get; set; }
virtual public Company Company { get; set; }
public ICollection<Order> Orders
{
get => LazyLoader.Load(this, ref _orders);
set => _orders = value;
}
}
And after iterating on orders data will be fetched
using(var db = new YourContext())
{
var customers = db.Customers.ToList();
foreach(var customer in customers )
{
Console.WriteLine($"Customer: {customer.Name} {customer .LastName}");
foreach(var order in customer.Ortders) // lazy loading initiated
{
Console.WriteLine($"\t{order.Id}");
}
}
}
I'm Creating an Event Management asp.net core app, My Customer Entity is related with different Entities by many to many relations. know I want to filter my Customers depending on both Event Name and Main Category name Entities.
Here are my Entities
Customer
public class Customer
{
public int Id {get; set;}enter code here
public string Name { get; set; }
public IList<CustomerEvent> CustomerEvents { get; set; }
public IList<CustomerMainCategory> CustomerMainCategories { get; set; }
}
Event
public class Event
{
public int Id { get; set; }
public string EventName { get; set; }
public IList<CustomerEvent> CustomerEvents { get; set; }
}
CustomerEvent
public Class CustomerEvent
{
public int CustomerId { get; set; }
public Customer Customer { get; set; }
public int EventId { get; set; }
public Event Event { get; set; }
}
MainCategory
public class MainCategory
{
public int Id { get; set; }
public string MainCategoryName { get; set; }
public IList<CustomerMainCategory> CustomerMainCategories { get; set; }
}
CustomerMainCategory
public class CustomerMainCategory
{
public int CustomerId { get; set; }
public Customer Customer { get; set; }
public int MainCategoryId { get; set; }
public MainCategory MainCategory { get; set; }
}
I want to Filter Customers that have same main category in the specified event.
Thank You in advance!!
Something like this?
(untestet)
db.Customers.Where(
c => c.CustomerEvents.Any(ce => ce.Event.Id == x)
&& c.CustomerMainCategories.Any(mc => mc.MainCategory.Id == y)
).ToList();
I have these entities:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<Order> Orders { get; set; }
}
public class Order
{
public int Id { get; set; }
public int CustomerId { get; set; }
public Category Category { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
}
public class CustomerOrder
{
public int Id { get; set; }
public string Name { get; set; }
//Some other properties here...
public IEnumerable<Order> Orders { get; set; }
}
I'm using Linq to get a customer and his orders as follows:
var customers = dataContext.Set<Customer>();
return (from customer in customers
where customer.Id == id
select new CustomerOrder
{
Id = id,
Name = customer.Name,
Orders = customer.Orders
});
The above projects as expected. However, I need to retrieve the Category for each Order.
How can I do this by expanding the above Linq statement?
I'm new in Asp.Net and Entity Framework and i have a little issue.
I know u can help me , because its simple and i only know how to do it in PHP XD
I Have 2 models
public class Suppliers
{
public int ID { get; set; }
public int ID_Guard { get; set; }
public string Supplier{ get; set; }
public string Description { get; set; }
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd hh:mm tt}", ApplyFormatInEditMode = true)]
public DateTime Enter { get; set; }
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd hh:mm tt}", ApplyFormatInEditMode = true)]
public DateTime Exit { get; set; }
public virtual Guard Guard { get; set; }
}
public class Guard
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Suppliers> Suppliers{ get; set; }
}
controller
public class SuppliersController : Controller
{
private SuppliersContext db = new SuppliersContext();
public ActionResult Index()
{
return View(db.Suppliers.ToList());
}
}
And i wanna pass to the view the 2 table data and relate it
When i go to index show me all the suppliers data and show the Guard name( the person who registered the supplier enter and exit)
Well its solved
var results = from c in db.Suppliers
join cn in db.Guard on c.ID_Guard equals cn.ID
where (c.ID_Guard == cn.ID)
select new Models.MyViewModel{ Name= cn.Name, ID = c.ID, Supplier=c.Supplier, Description=c.Description, Enter=c.Enter, Exit=c.Exit};
follow the below code it works and seems same like yours also i added the link hope you find It helpful
public class Product
{
public Product() { Id = Guid.NewGuid(); }
public Guid Id { get; set; }
public string ProductName { get; set; }
public virtual ProductCategory ProductCategory { get; set; }
}
public class ProductCategory
{
public int Id { get; set; }
public string CategoryName { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
/////view model///
public class ProductViewModel
{
public Guid Id { get; set; }
[Required(ErrorMessage = "required")]
public string ProductName { get; set; }
public int SelectedValue { get; set; }
public virtual ProductCategory ProductCategory { get; set; }
[DisplayName("Product Category")]
public virtual ICollection<ProductCategory> ProductCategories { get; set; }
}
follow the below tutorial
relationship model
for basic join use below query
var dealercontacts = from contact in table1
join table2 in table2 on contact.Id equals another.ID
select contact;
I'm wondering if its possible to have a property/field in a class that is populated directly from a database. I know that directly implementing this would break design patterns, such as separation of concerns, but I'm hoping to have some configuration in the OnModelCreating function of my DbContext.
In the example below, given a Product, I'd like to find out on which PriceTables it appears:
public class PriceTable
{
public int ID { get; set; }
public HashSet<Price> Prices { get; set; }
public PriceTable()
{
Prices = new HashSet<Price>();
}
}
public class Price
{
public int ID { get; set; }
public double Value { get; set; }
public int ProductID { get; set; }
public virtual Product Product { get; set; }
public int PriceTableID { get; set; }
public virtual PriceTable PriceTable { get; set; }
}
public class Product
{
public int ID { get; set; }
public String Name { get; set; }
// This is what I'd like to achieve
/*
public HashSet<PriceTable> PriceTables {
get {
// and here, return something from the DB
}
}
*/
}
Just to clarify: my model is not like the one below, but it works on the same way (so that I need this separation of classes, with this "junction table").
AFAIK, using LINQ I could find the information I want with the following:
from p in Prices
where p.Product.ID == MY_PRODUCT_ID
select p.PriceTable
Which means that is the query I'd like to embed in my Product class!
Thanks in advance!
I accomplished my objectives by changing the model to match the following (with changes described as comments):
public class PriceTable
{
public int ID { get; set; }
public HashSet<Price> Prices { get; set; }
// New field, which allows me to query "all the Products in some PriceTable"
public IEnumerable<Product> Products
{
get
{
return Prices.Select(p => p.Product);
}
}
public PriceTable()
{
Prices = new HashSet<Price>();
}
}
public class Price
{
public int ID { get; set; }
public double Value { get; set; }
public int ProductID { get; set; }
public virtual Product Product { get; set; }
public int PriceTableID { get; set; }
public virtual PriceTable PriceTable { get; set; }
}
public class Product
{
public int ID { get; set; }
public String Name { get; set; }
// New field, previsouly automatically generated by EF4
public HashSet<Price> Prices { get; set; }
// New field, which allows me to query "all the PriceTables on which a Product appears"
public IEnumerable<PriceTable> PriceTables
{
get
{
return Prices.Select(p => p.PriceTables);
}
}
}