EF Core complex query - sql

this is the entity
public class Order
{
public int Id {get;set;}
public int ProductName {get;set;}
}
public class BuyerBill
{
public BuyerBill()
{
BuyerBillItems = new List<BuyerBillItems>();
}
public int Id {get;set;}
public int OrderId {get;set;}
public int Status {get;set;}
public List<BuyerBillItems> BuyerBillItems { get; set; }
....
}
public class BuyerBillItems
{
public int Id {get;set;}
public int BuyerBillId {get;set;}
public int Fee {get;set;}
....
}
public class SellerBill
{
public SellerBill()
{
SellerBillItems= new List<SellerBillItems>();
}
public int Id {get;set;}
public int OrderId {get;set;}
public int Status {get;set;}
public List<SellerBillItems> SellerBillItems{ get; set; }
....
}
public class SellerBillItems
{
public int Id {get;set;}
public int SellerBillId {get;set;}
public int Fee {get;set;}
....
}
select sum(e2.Fee) from order e
join BuyerBill on e.Id=e1.OrderId
join BuyerBillItems e2 on e1.Id=e2.BuyerBillId
where e.Id=1
select sum(e2.Fee) from order e
join SellerBill on e.Id=e1.OrderId
join SellerBillItems e2 on e1.Id=e2.SellerBillId
where e.Id=1
There is only one row of order records in the SellerBill and SellerBill tables
BuyerBillItems and SellerBillItems tables may have many rows
I can only query with 2 T-SQL statements now, how can I query with one T-SQL?
My project is using EF CORE, so you guys better help me to query with EF CORE, thanks!
The result I want to get is
BuyerFee,SellerFee
200,100

Related

Get Value from other Table by ID with Entity Framework

i have two already existings tables (no foreignkey):
Customer (Id, Name, .....)
Projects (Id, CustomerId, name)
And in my asp.net core application i have two model:
public class Customer {
public int Id { get; set; };
public String Name { get; set; };
}
public class Project {
public int Id { get; set; };
public Customer Customer{ get; set; };
public String Name{ get; set; };
}
And the datacontext classes for this
public class CustomerContext: DbContext
{
public CustomerContext(DbContextOptions<CustomerContext> options) : base(options)
{
}
public DbSet<CustomerContext> Customer { get; set; }
}
public class ProjectContext: DbContext
{
public ProjectContext(DbContextOptions<ProjectContext> options) : base(options)
{
}
public DbSet<ProjectContext> Project{ get; set; }
}
But i cant find out how to fetch the Customer object in the Projectclass by the customerId
Can someone help me please? Thank you
Edit: Now i change my Model Classes like in the answer below
but with the following i get an SQL Exception while loading the page
SqlException: Invalid object name 'Customer'.
projectList = await (from project in _context.Project
join customer in _customerContext.Customer on project.CustomerId equals customer.Id into tmp
from m in tmp.DefaultIfEmpty()
select new Project
{
Id = sollIst.Id,
CustomerId = sollIst.CustomerId,
Customer = m,
Name = sollIst.Name,
}
).ToListAsync();
Update your model classes as below:
public class Customer {
public int Id { get; set; };
public String Name { get; set; };
}
public class Project {
public int Id { get; set; };
public String Name{ get; set; };
public int CustomerID { get; set; }
[ForeignKey("CustomerID")]
public Customer Customer{ get; set; };
}
Merger both DbContext into one.
public class ProjectContext: DbContext
{
public ProjectContext(DbContextOptions<ProjectContext> options) : base(options)
{
}
public DbSet<Project> Projects { get; set; }
public DbSet<Customer> Customers { get; set; }
}
Then execute
projectList = await (from project in _context.Project
join customer in _context.Customer on project.CustomerId equals customer.Id into tmp
from m in tmp.DefaultIfEmpty()
select new Project
{
Id = sollIst.Id,
CustomerId = sollIst.CustomerId,
Customer = m,
Name = sollIst.Name,
}
).ToListAsync();
I hope following links will help you to know how to join two tables across different database.
Joining tables from two databases using entity framework.
Entity framework join across two databases
You will have to create a property in Project class that represent the "foreign key".
Lets say in Project table in the database the "foreign key" is CustomerID, add this to Project class:
public int CustomerID { get; set; }
Then add the ForeignKey attribute to the Customer property:
[ForeignKey("CustomerID")]
public Customer Customer { get; set; }
First, your model classes should be as follows:
public class Customer {
public int Id { get; set; };
public string Name { get; set; };
}
public class Project {
public int Id { get; set; };
[ForeignKey("Customer")]
public int CustomerId{ get; set; };
public string Name{ get; set; };
public Customer Customer { get; set; };
}
Then your DbContext classes should be as follows:
public class CustomerContext: DbContext
{
public CustomerContext(DbContextOptions<CustomerContext> options) : base(options)
{
}
public DbSet<Customer> Customers { get; set; }
}
public class ProjectContext: DbContext
{
public ProjectContext(DbContextOptions<ProjectContext> options) : base(options)
{
}
public DbSet<Project> Projects { get; set; }
}
Now you can use Entity Framework Core and LINQ query to fetch your desired data.

castle activerecord lazy get id

I have these two classes
[ActiveRecord("Customers", Lazy=true)]
public class Customer : ActiveRecordBase<Customer>
{
[PrimaryKey(PrimaryKeyType.Identity, Access = PropertyAccess.AutomaticProperty)]
public virtual int Id { get; private set; }
[Property]
public virtual string Name { get; set; }
[HasMany(Lazy = true)]
public virtual IList<Order> Orders { get; set; }
}
[ActiveRecord("Orders", Lazy=true)]
public class Order : ActiveRecordBase<Order>
{
[PrimaryKey(PrimaryKeyType.Identity, Access = PropertyAccess.AutomaticProperty)]
public virtual int Id { get; private set; }
[Property]
public virtual string Product { get; set; }
[BelongsTo(Lazy = FetchWhen.OnInvoke)]
public virtual Customer Customer { get; set; }
}
I want to select all orders and foreach of them, get the id of the customer.
So I do this:
using (new SessionScope())
{
var orders = Order.FindAll();
foreach (var o in orders)
{
int id = o.Customer.Id;
}
}
It works, but it creates a SELECT phrase for each call to o.Customer.Id.
Now, the Order already has the Id of the customer, so how can I get it without revisiting the database??
the following code should allow you to get the id (but I couldn't test it at the moment):
int id = (int)((INHibernateProxy)order.Customer).HibernateLazyInitializer.Identifier;
Greetings
Juy Juka

Fetch multiple in NPoco when children has its own mapping to do

I have been successful with fetching a parent and its children with NPoco FetchManyToOne with this code:
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public IList<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
}
db.FetchOneToMany<Parent, Child>(parent => parent.Id, child => child.Id,
#"SELECT
P.Id, P.Name,
C.Id, C.ParentId, C.Name
FROM Parent AS P
LEFT JOIN Child AS C ON P.Id = C.ParentId",
id);
Now there is this scenario when a child can belong to a period. A children does not have to belong to a period as this is optional.
In the database the Period table consists of an id column and two datetime columns, Start and End. The Child table has a new column, PeriodId which can contain a null value if it does not belong to a period.
The class Child now gets a new property of type Period. Which can be null or an instance of class Period.
Look at the changes to the class structures:
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public IList<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
public Period ChildPeriod { get; set; }
}
public class Period
{
public int Id { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
How can I map this sql to my classes?
#"SELECT
P.Id, P.Name,
C.Id, C.ParentId, C.Name,
PE.Id, PE.Start, PE.End
FROM Parent AS P
LEFT JOIN Child AS C ON P.Id = C.ParentId
LEFT JOIN Period AS PE ON C.PeriodId = PE.Id"
So that when a child is a part of a period that period is the value of property ChildPeriod on class Child.
Is it possible or do I have to write two calls to the database and do some manual mapping myself?
Since that's really an outer join on Period where Period will sometimes be null, do your Child class as:
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
[ResultColumn] public DateTime? Start { get; set; }
[ResultColumn] public DateTime? End { get; set; }
}

Multiple Primary Key with asp .net mvc 3

I'm using asp .net mvc 3, and I have a problem with an entity that contains 2 primary key, when I try to insert data in the table.
public class LineItem
{
[Key]
public int OrderId { get; set;}
[Key]
public int LineNum { get; set;}
public string ItemId { get; set;}
public int Quantity { get; set;}
public decimal UnitPrice { get; set; }
}
when I try to insert I got this error :
Unable to determine composite primary
key ordering for type
'ApplicationMVC3.Models.LineItem'. Use the
ColumnAttribute or the HasKey method
to specify an order for composite
primary keys.
May someone help me please !!
Assuming this is actually a composite key, since you can't have 2 primary keys... The error message tells you exactly what to do, namely add an order. You can do this by adding [Column(Order = 0)] and [Column(Order = 1)] to your key columns.
For your example:
public class LineItem
{
[Key][Column(Order = 0)]
public int OrderId { get; set;}
[Key][Column(Order = 1)]
public int LineNum { get; set;}
public string ItemId { get; set;}
public int Quantity { get; set;}
public decimal UnitPrice { get; set; }
}

Polymorphic nhibernate query with projection

Using a single table for a class hierarchy I would like to use a projection to flatten the hierarchy to present a list of results to the user.
Is there a way to do this using HQL or Criteria API without having to issue multiple separate queries or unions?
Classes
public class A {
public virtual long Id { get; set; }
}
public class B : A {
public virtual DateTime SomeDate { get; set; }
public virtual OtherEntity Other { get; set; }
}
public class C : A {
public virtual DateTime? SomeDate { get; set; }
public virtual string Description { get; set; }
}
public class D : A {
public virtual string Description { get; set; }
}
public class OtherEntity {
public virtual string Name { get; set; }
}
SQL Tables:
CREATE TABLE Items (
Id bigint NOT NULL PRIMARY KEY,
Kind char(1) NOT NULL,
SomeDate datetime NULL,
Description NULL
)
CREATE TABLE OtherEntity (
Id bigint NOT NULL PRIMARY KEY,
Name nvarchar(255) NOT NULL
)
Output projection:
public class ItemReport {
// From A.Id
public virtual long Id { get; set; }
// From B.SomeDate or C.SomeDate
public virtual DateTime? SomeDate { get; set; }
// From C.Description or D.Description
public virtual string Description { get; set; }
// From B.OtherEntity.Name
public virtual string OtherName { get; set; }
}