SQL to LINQ inner JOIN - c#

Could somebody help me form the below SQL query in Entity framework linq?
The AccountApplication-table has got two FK's:
AccountApplication[AccountId]->Account[AccountId]
and
AccountApplication [ApplicationId] -> Application[ApplicationId]
select * from Invoice a inner join AccountApplication b
on b.AccountId = 3 and b.ApplicationId = a.ApplicationId
I do not have the AccountApplication entity table available in EF.
What I want is a list of invoice who belongs to the application(s) what the given account id has rights to. And the relation between accountid's applicationid's are in the AccountApplication-table.
Screenshot of EF classes with navigation properties

With navigation properties it's quite simple
var query = db.Invoices.Where(invoice => invoice.Application.Account
.Any(account => account.AccountId == 3));
I hope you see now why they are called navigation properties. Inside the query you use them to "navigate" (access) the data needed, and the EF uses them as metadata for generating the necessary joins.

var records= (from a in context.Invoices join b in context.AccountApplication
on a.accountId equals b.accountId
where b.accountId==3
select new {a.Id,b.Id,....etc});

Related

C# & Entity Framework : return specific columns from a 3 table join

I have a C# application where I am using Entity Framework to pull data from a database. This is the code I am executing:
var person = new List<Person>();
using (DevTestEntities db = new DevTestEntities())
{
person = (from p in db.People
join e in db.PersonEmails on p.Id equals e.Id
join t in db.PersonPhones on p.Id equals t.Id
where t.Phone == phoneNumber
select p).ToList();
}
var str = Newtonsoft.Json.JsonConvert.SerializeObject(person);
return str;
When the code runs, it fails on the select. I assume it is failing because there is a table within the database that is not part of the model. And because there is just a generic select, I assume Entity Framework is selecting all columns from all tables and doesn't know what to do with some of the columns.
What I really want to do is to be able to specify the columns that I want to return to the calling function. How do I specify what columns Entity Framework should select?
Thanks for any assistance.
EF will not fail because of tables in the DB that are not in model. It would help if you provided the error. Also, your query will result in selecting all columns from the People table but not the others.
An example answer to your question is this, it selects three columns from different tables and puts them in a new anonymous type:
var onlySomeColumns = (from p in db.People
join e in db.PersonEmails
on p.Id equals e.Id
join t in db.PersonPhones
on p.Id equals t.Id
where t.Phone == phoneNumber
select new {p.Id, e.email, t.phonenumber}).ToList();

Group child list into single parent object - AdventureWorks query - Lambda Expression

I am working with the AdventureWorks database and I am using the following query :
SELECT c.CustomerID, c.AccountNumber, soh.SalesOrderID, soh.SalesOrderNumber, sod.UnitPrice, sod.ProductID, p.Name
FROM Sales.SalesOrderHeader soh
inner join sales.SalesOrderDetail sod on soh.SalesOrderID = sod.SalesOrderID
inner join sales.Customer c on c.CustomerID = soh.CustomerID
inner join Production.Product p on p.ProductID = sod.ProductID
I have code already that populates the data like this just as it comes back:
Based on that I am wanting to merge the child list objects into a single parent to end up with a one to many structure if that makes sense.
As of right now I am hoping to use a lambda expression to do this. I have tried the following code but I don't want to have to specify --> o.CustomerID, o.AccountNumber in the group by because i would have to specify ALL the properties of my Customer class to have access to the final select as you can see in the code.
.GroupBy(o => new { o.CustomerID, o.AccountNumber }).Select(group => new Customer2
{
CustomerID = group.Key.CustomerID,
AccountNumber = group.Key.AccountNumber,
Orders = group.SelectMany(x => x.Orders).ToList()
}).ToList();
I would like the end result to look like this for each customer:
I hope this makes sense and thanks in advance for the help.

Outerjoin with a table of foreign keys in EF Data-first approach

I have a table Users which contain user information. I have a table Products which contain product information. I have a table called UserProduct which acts as a junction table and whose fields are UserId and ProductId. I am using a Entity Framework database first approach.
I want to outerjoin using Linq to find the following data.
All Users in the Users table.
All Users who have bought a particular product in terms of a Boolean called isPurchased.
My thinking was to left outer join table User with UserProduct and get all users and whether they have a product something like this.
var result = from a in Users
join b in UserProduct(Not available through EF) on a.Id equals b.prodId into group1
from g1 in group1.DefaultIfEmpty()
select new
{
id = g1.Id,
isPurchased = g1.prodId != null
}.ToList();
However in EF mapping, the object UserProduct is not created and so I cannot use it directly in my Linq query? So how do I go about this? Is there a way I can use linq to join tables with the actual table name(UserProduct) instead of joining entities?
Assuming Users contains a property List<Products> products to represent the junction information, and a variable boughtProductId to represent the particular product:
var result = from u in Users
let isPurchased = u.products.Any(p => p.Id == boughtProductId)
select new {
id = isPurchased ? boughtProductId : null,
isPurchased
}.ToList();

NHibernate: How to eager fetch sub entities with a filter over sub entity through one sql query without lazyload?

I'am using NHibernate 3.3.1 with FluentNhibernate 1.3 for Data Layer.
I have the following entities:
Database Diagram:
I need a method that gets the Products by MediaCategory of Medias of Products. I want NHibernate to send only one query to db and fetch all sub properties of products.
I want NHibernate send a query like this:
declare #mediaCategoryId int = 13
select *
from Product p
inner join Media m on m.ProductId=p.Id
inner join MediaCategoryMedia mcm on mcm.MediaId=m.Id
inner join MediaCategory mc on mc.Id=mcm.MediaCategoryId
left join ProductSeller ps on ps.ProductId=p.Id
left join Seller s on ps.SellerId=s.Id
where mc.Id=#mediaCategoryId
I have tried the following options to solve this challenge;
session.QueryOver< ProductEntity >()...
I have tried Inner.JoinQueryOver< .. >().Fetch.Eager... but I couldn't fetch all the sub entities.
session.CreateCriteria< ProductEntity >().SetFetchMode("",FetchMode.Eager)...
In this case lazy load works and I dont want lazyload. If I disable lazyload from mappings NH sends lots of queries.. what I want is eager load with one single query that fetches all sub entities.
session.Query< ProductEntity >().FetchMany(p=>p.MediaList).ThenFetchMany(m=>m.SellerList)...
I couldn't create alias to pass mediaCategoryId filter in this case. Instead I used .Where(x=>x.MediaList.Any(m=>m.CategoryList.Any(...))) and the query generated is not optimum, too.
(from p in session.Query< ProductEntity >()
from m in p.MediaList
from c in m.MediaCategoryList
where c.Id==23
select p).Fetch(x=>x.MediaList);
this didn't work as I wanted, too..
var hql=#"select p from ProductEntity as p join fetch p.MediaList as m join fetch m.MediaCategoryList as mc left join fetch p.SellerList as s where mc.Id=:catId ";
THIS WORKS with "join fetch" in hql.
I need the best practice of this case, however Hql is the king.
Can we handle this case with session.Query<>() or session.CreateCriteria, or QueryOver ?
For a direct translation of your query...
Media mediaAlias = null;
MediaCategory categoryAlias = null;
return session.QueryOver<Product>()
.JoinAlias(x => x.Medias, () => mediaAlias)
.JoinAlias(() => mediaAlias.Categories, () => categoryAlias)
.Fetch(x => x.Sellers).Eager
.Where(() => categoryAlias.Id == mediaCategoryId)
.List();
JoinAlias does an inner join by default, and Fetch(...).Eager does a left outer join. JoinAlias allows us to dig down through Media to the categories, and it also eagerly fetches the data.
Note that there is a Cartesian product between Sellers and Medias in this query. If there are 20 Medias and 20 Sellers on a single Product, then this query would return 20 * 20 = 400 rows, which is not ideal for performance. You can address this by splitting the Media fetching and the Seller fetching into separate queries, but batch them together in one round-trip to the database using Future(), meaning the query would return 20 + 20 = 40 rows. Much better.
Also, this query will not return all of the categories associated with a Media. If you need this, then you should apply the mediaCategoryId constraint in an Exists sub-query.

Updating multiple tables at the same time in Linq-to-SQL

How do I update two tables at the same time using Linq-to-SQL?
var z = from a in db.Products
join b in db.ProductSubcategories on
a.ProductSubcategoryID equals b.ProductSubcategoryID
join d in db.ProductCategories on
b.ProductCategoryID equals d.ProductCategoryID
select new { ProductName = a.Name, ProductCategory = d.Name,
ProductSubCategory = b.Name, Cost = a.StandardCost,
discontinuedDate = a.DiscontinuedDate,
ProductId=a.ProductID };
You have to update individual records from each table and then execute db.SubmitChanges();
In your query the output is an anonymous type, not a table type connected to the db context.
If you think in terms of SQL, linq2sql works pretty much the same. You can select a record set with a join, but you cannot update directly on this. You need to break it up and modify entries directly on Products, ProductCategories and ProductSubCategories, which equals the tables in your database.
If you want to modify a Product in Products then you have to modify the properties of that type, and not the anonymous type (joined type).

Categories