LINQ Join with where condition - asp.net-mvc

I can use LINQ's Join with Lambda notations no problem, but I can't work out how one would then add a where condition.
var q = query.Join(context.CustomerIds,
x => x.CustomerId,
y => y.CustomerId,
(x, y) => new CustomerLookupResult()
{
dob = x.DateOfBirth.ToString(),
forenames = x.Forenames,
surname = x.Surname,
loyaltyNo = y.Identifier,
customerId = x.CustomerId
});
The table I'm joining the first to contains the loyaltyNo in its Identifier column, but also contains other information in the same column and so uses a second column IdentifierTypeCode to allow filtering.
So how do I now add .Where(x => x.IdentifierTypeCode == "LOYALTY") like I would in SQL. Appending this to end refers to the new object.

You could apply your Where before doing the join.
var q = customerLoyalties
.Where(x => x.IdentifierTypeCode == "LOYALTY")
.Join(customers,
x => x.CustomerId,
y => y.CustomerId,
(x, y) => new CustomerLookupResult()
{
CustomerId = y.CustomerId,
Name = y.Name,
IdentifierTypeCode = x.IdentifierTypeCode
});

You can also use this way to achieve that using Linq.
var match = from t1 in context.orders
join t2 in context.orderdetails on
new { t1.OrderID } equals
new { t2.OrderID }
join t3 in context.products on
new { t2.ProductID } equals
new { t3.ProductID }
where t3.ProductID == id
select t3;
return match.ToList();

The first parameter to the Join takes any IEnumerable, so you can apply the Where at that point, or earlier
var q = query.Join(context.CustomerIds.Where(x=>x.IdentifierTypeCode=="LOYALTY"),
x => x.CustomerId,
y => y.CustomerId,
(x, y) => new CustomerLookupResult()
{
dob = x.DateOfBirth.ToString(),
forenames = x.Forenames,
surname = x.Surname,
loyaltyNo = y.Identifier,
customerId = x.CustomerId
});
alternatively, if you don't like to put too much on one line:
var filteredLoyalties = context.CustomerIds.Where(x=>x.IdentifierTypeCode=="LOYALTY");
var q = query.Join(filteredLoyalties,
...

Related

Apply Groupby in EF with suitable results

I am not much familiar with EF. I want to group rows based on IDs. I acheive this in SQL but I am getting some Issues with group by while implementeing in EF.
public ActionResult PropertyListing()
{
if (Session["UserID"] == null)
{
return RedirectToAction("Login", "Property");
}
return View();
}
public JsonResult GetSpurts()
{
PropertySpurts property;
List<PropertySpurts> listProperty = new List<PropertySpurts>();
var userID = Convert.ToInt32(Session["UserID"].ToString());
// IEnumerable<tblPropertyView> PropertyList;
var PropertyList = from p in dbEntity.tblPropertyViews
join c in dbEntity.tblProperties on p.PropertyID equals c.ID into j1
from j2 in j1.DefaultIfEmpty()
group j2 by p.PropertyID into grouped
select new { ParentId = grouped.Key, Count = grouped.Count(t => t.ID != null) };
if (PropertyList != null)
{
foreach (var item in PropertyList)
{
property = new PropertySpurts();
property.ID = (int)item.ParentId;
property.Title = item.tblProperty.Title;
listProperty.Add(property);
}
}
return Json(listProperty, JsonRequestBehavior.AllowGet);
}
PropertyID in tblPropertyView is Foreign Key to tblProperty ID. I want to get title of Property from tblProperty. Please help me to find Title and Count of PropertyViews
TIA
[SOLVED]
var PropertyList = from p in dbEntity.tblPropertyViews
join c in dbEntity.tblProperties on p.PropertyID equals c.ID into j1
from j2 in j1.DefaultIfEmpty()
group j2 by new
{
p.PropertyID,
p.tblProperty.Title
} into grouped
select new
{
ParentId = grouped.Key.PropertyID,
Title = grouped.Key.Title,
Count = grouped.Count(t => t.ID != null)
};
This solves my issue. But I want this should be orderby count.
var PropertyList = (from p in dbEntity.tblPropertyViews
join c in dbEntity.tblProperties on p.PropertyID equals c.ID into j1
from j2 in j1.DefaultIfEmpty()
group j2 by new
{
p.PropertyID,
p.tblProperty.Title
} into grouped
select new
{
ParentId = grouped.Key.PropertyID,
Title = grouped.Key.Title,
Count = grouped.Count(t => t.ID != null)
}).OrderByDescending(x => x.Count);

Select query from 2 table using entity framework

select p.ProduitNom,v.VonduDate,p.ProduitPrix from Produits p,Vondus v
where p.ProduitId = v.ProduitId and p.CentreId=1
How to do this request in entity framework ?
You can do that as shown below.
Inner Join :
from p in db.Produits
join v in db.Vondus on p.ProduitId equals v.ProduitId
where p.CentreId=1
select new {
ProduitNom = p.ProduitNom,
VonduDate = v.VonduDate,
ProduitPrix = p.ProduitPrix
}
If you would like to learn,you can refer this : Queries in LINQ to Entities
You can use Join:
EDIT:
You should have a context to connect with Database first, or else, at least 2 lists:
List<Produits> Produits = new List<Produits>();
List<Vondus> Vondus = new List<Vondus>();
Then using below lambda expression:
var res = Produits.Join(Vondus, p => p.ProduitId, v => v.ProduitId,
(p, v) => new { p, v })
.Where(pv => pv.p.ProduitId == pv.v.ProduitId && pv.p.CentreId == 1)
.Select(pv => new { pv.p.ProduitNom, pv.v.VonduDate, pv.p.ProduitPrix)
.ToList();
The res will be a list containts of ProduitNom, VonduDate and ProduitPrix

How to create linq query to join rows into string?

I have a table with the following fields:
Id Name Score Event
(1 John 2 3)
(2 John 4 3)
(3 john 5 3)
and I would like to get the following result:
(John, "2 +4+5", 11(Total score))
I'm trying to combine the results to show the sum in a string format then show the sum result.
Can anyone please help me with this issue.
Thank you,
Franciso
You need to call the toList() method before using methods like string.Format or string.Join because they are not supported by Linq to SQL.
You should modify your code into something like this:
var group = (from Classificacao in _dbSet.classificacao
from Evento in _dbSet.evento
where Classificacao.class_id_Evento == id_evento
where Evento.id_evento == id_evento
group Classificacao by new
{
Classificacao.class_atletaNome,
Classificacao.class_numAtleta,
Classificacao.class_atletaEquipa,
Classificacao.class_paisAtleta,
Evento.even_name,
Evento.local.local_nome,
Evento.compTipo.CompTipo_name
} into g).ToList()
The idea is to materialize the query into a list before calling the methods.
var model = group.Select(g => new
{
g.Key.class_numAtleta,
g.Key.class_atletaEquipa,
g.Key.class_atletaNome,
g.Key.class_paisAtleta,
class_fianlAtleta = g.Sum(c => c.class_fianlAtleta.Value),
class_classGeral = g.Min(c => c.class_fianlAtleta.Value),
class_nome = g.Key.even_name,
local_nome = g.Key.local_nome,
CompTipo_name = g.Key.CompTipo_name,
class_40ponto = ((from u in g
where u.class_id_Evento == id_evento
group u by new
{
u.class_atletaNome,
u.class_fianlAtleta
}
into k
select new
{
//Score = string.Concat(k.Key.class_fianlAtleta.ToString(), " + ", g.Key.class_atletaNome)
Score = string.Format("{0}",k.Key.class_fianlAtleta)
})).Select(c=>c.Score).FirstOrDefault()
}).OrderBy(c => c.class_fianlAtleta).ThenBy(c => c.class_classGeral)).toList();
I can't check if the code is correct therefore I leave it to you, anyway once you have your List in memory you can apply the methods supported by Linq to entity.
Here is my code:
var model = (from Classificacao in _dbSet.classificacao
from Evento in _dbSet.evento
where Classificacao.class_id_Evento == id_evento
where Evento.id_evento == id_evento
group Classificacao by new
{
Classificacao.class_atletaNome,
Classificacao.class_numAtleta,
Classificacao.class_atletaEquipa,
Classificacao.class_paisAtleta,
Evento.even_name,
Evento.local.local_nome,
Evento.compTipo.CompTipo_name
} into g
select new
{
g.Key.class_numAtleta,
g.Key.class_atletaEquipa,
g.Key.class_atletaNome,
g.Key.class_paisAtleta,
class_fianlAtleta = g.Sum(c => c.class_fianlAtleta.Value),
class_classGeral = g.Min(c => c.class_fianlAtleta.Value),
class_nome = g.Key.even_name,
local_nome = g.Key.local_nome,
CompTipo_name = g.Key.CompTipo_name,
class_40ponto = ((from u in g
where u.class_id_Evento == id_evento
group u by new
{
u.class_atletaNome,
u.class_fianlAtleta
}
into k
select new
{
//Score = string.Concat(k.Key.class_fianlAtleta.ToString(), " + ", g.Key.class_atletaNome)
Score = string.Format("{0}",k.Key.class_fianlAtleta)
})).Select(c=>c.Score).FirstOrDefault()
}).OrderBy(c => c.class_fianlAtleta).ThenBy(c => c.class_classGeral);de here
You need something like this:
var result = table
.GroupBy(t => new { t.Name, t.Event })
.ToList()
.Select(t => new
{
Name = t.Key.Name,
JoinedScores = string.Join(" + ", t.Select(group => group.Score).ToArray()),
TotalScore = t.Sum(group => group.Score).ToString() + " (Total Score)"
}).ToList();
The first call to the ToList() method is needed because Linq to SQL will not support the calls to string.Join(). I'm not sure but probably you can replace it with a call to AsEnumerable().

Linq query, how to orderby

I have a method that gets some data from the database by some linq queries. The data is shown as expected but not in the order I wan't. I need to sort the products I get from the database by the TotalQuantity property shown in query 1 and 2. Im trying to use OrdeBy but I'm not sure how to add it in this context. Need some help with this one.
This is my method:
public IList<BestsellersReportLine> DailyBestsellersReport()
{
OrderStatus os;
PaymentStatus ps;
ShippingStatus ss;
int billingCountryId = 0;
int recordsToReturn = 10;
int orderBy = 1;
int groupBy = 1;
var range = new
{
startTimeUtc = DateTime.Today.AddDays(-1),
endTimeUtc = DateTime.Today.AddSeconds(-1),
CreatedOnUtc = DateTime.Today.AddDays(-1),
};
var query1 = from opv in _opvRepository.Table
join o in _orderRepository.Table on opv.OrderId equals o.Id
join pv in _productVariantRepository.Table on opv.ProductVariantId equals pv.Id
join p in _productRepository.Table on pv.ProductId equals p.Id
where (o.CreatedOnUtc >= range.startTimeUtc && o.CreatedOnUtc <= range.endTimeUtc)
select opv;
var query2 = groupBy == 1 ?
//group by product variants
from opv in query1
group opv by opv.ProductVariantId into g
select new
{
EntityId = g.Key,
TotalAmount = g.Sum(x => x.PriceExclTax),
TotalQuantity = g.Sum(x => x.Quantity),
}
:
//group by products
from opv in query1
group opv by opv.ProductVariant.ProductId into g
select new
{
EntityId = g.Key,
TotalAmount = g.Sum(x => x.PriceExclTax),
TotalQuantity = g.Sum(x => x.Quantity),
};
switch (orderBy)
{
case 1:
{
query2 = query2.OrderByDescending(x => x.TotalQuantity);
}
break;
case 2:
{
query2 = query2.OrderByDescending(x => x.TotalAmount);
}
break;
default:
throw new ArgumentException("Wrong orderBy parameter", "orderBy");
}
if (recordsToReturn != 0 && recordsToReturn != int.MaxValue)
query2 = query2.Take(recordsToReturn);
var result = query2.ToList().Select(x =>
{
var reportLine = new BestsellersReportLine()
{
EntityId = x.EntityId,
TotalAmount = x.TotalAmount,
TotalQuantity = x.TotalQuantity
};
return reportLine;
}).ToList();
return result;
}
What about return
result.OrderBy(x => x.totalQuantity).ToList();
Update:
I can only think of adding .ToList() to the end again.
Remove the first ToList() after query2 as mentioned below:
var result = query2.Select(x =>
{
var reportLine = new BestsellersReportLine()
{
EntityId = x.EntityId,
TotalAmount = x.TotalAmount,
TotalQuantity = x.TotalQuantity
};
return reportLine;
}).ToList();

Returning property and count columns together in Neo4jClient Cypher Query

I have a Cypher query likes this:
START n=node:permit_idx(PmtID= "111")
Match n-[:Assinged]->m<-[:Assinged]-p
RETURN p.PmtID, count(m);
I got error when I try to do it using Neo4jClient Cypher Query
var results = graphClient
.Cypher
.Start(new { n = Node.ByIndexLookup("permit_idx", "PmtID", "111") })
.Match("Match n-[:Assigned]->m<-[:Assigned]-p")
.Return((m, p) => new
{
PDPmtID = "p.PmtID",
MCount = "count(m)"
})
.Results;
If only need to return one property or one count, we can use
.Return<int>("count(m)");
But how to return property and count together?
.Return((m, p) => new
{
PDPmtID = Return.As<int>("p.PmtID"),
MCount = m.Count()
})
Or, preferred right now:
.Return((m, p) => new
{
Permit = p.As<Permit>(),
MCount = m.Count()
})
You need to use the custom text option in your compound Return clause:
.Return((m, p) => new
{
PDPmtID = Return.As<int>("p.PmtID"),
MCount = Return.As<int>("count(m)")
})
(This is based on the documentation for the Neo4jClient)

Resources