List of Users with their single Role in MVC 6 left joined - asp.net-core-mvc

Using VS 2015, MVC 6 RC1 and EF 7 RC1 I'm trying to get a list of all users with their single role name.
I have tried all suggestions I have come across on StackOverflow but none have worked.
The SQL I'm looking for is:
SELECT [User].[Email], [Role].[Name]
FROM [User]
LEFT JOIN [UserRoles] ON [User].[Id] = [UserRoles].[UserId]
LEFT JOIN[Role] ON [UserRoles].[RoleId] = [Role].[Id]
I have written the below and tested on LinqPad (works fine) and should have worked in my project but comes up with an error:
var q1 = (from user in _context.Users
join ur in _context.UserRoles on user.Id equals ur.UserId into grp1
from fgrp1 in grp1.DefaultIfEmpty()
join r in _context.Roles on fgrp1.RoleId equals r.Id into grp2
from fgrp2 in grp2.DefaultIfEmpty()
select new { UserEmail = user.Email, UserRoleName = fgrp2.Name }).ToList();
And the error message is:
An unhandled exception occurred while processing the request.
InvalidOperationException: Sequence contains no elements
System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
I don't know if it makes any difference but I have created my own Role Entity as:
public class ExtranetRole : IdentityRole<int> { }
and my own User entity as:
public class ExtranetUser : IdentityUser<int> { }
Any help/suggestions much appreciated.

EF7 RC1 have some bugs, related to LEFT joins. Check https://github.com/aspnet/EntityFramework/issues/3629 - it looks very similar to your problem.
I think the best solution until EF release is just read all three tables separately and join them in memory using linq (to objects). Guaranteed to work :)

Related

How to fetch lazy collection in QueryDSL 4

I have a following problem with executing quite simple query with querydsl. Imagine that we have two entities:
CAR ----< OWNERS
I would like to execute query which returns all cars and fetches all its owners which are mapped lazily. In other words, I would like to fetch those to be used outside of transaction.
My query looks like:
List<Car> cars = new JPAQuery<Car>(em)
.select(car).from(car)
.leftJoin(car.owners, owner)
.where(car.make.eq(make))
.orderBy(new OrderSpecifier<>(Order.ASC, car.id))
.distinct()
.fetch();
Similar query worked fine in QueryDSL 3, but after upgrade to 4 I am getting LazyInitializationException, which means that 'owners' are not fetched properly. Could you please shed some light on how to solve this problem?
For example when I write this query manually it works completely fine:
List<Car> cars = em.createQuery(
"SELECT DISTINCT c FROM Car c LEFT JOIN FETCH c.owners WHERE c.make = :make ORDER BY c.id ASC")
.setParameter("make", make).getResultList();
I am using spring-boot 2 with querydsl 4.1.4
BTW, query which worked fine in querydsl 3
List<Car> car = new JPAQuery(em)
.from(car)
.leftJoin(car.owners)
.fetch()
.distinct()
.where(car.make.eq(make))
.orderBy(new OrderSpecifier<>(Order.ASC, car.id))
.list(car);
after multiple attempts I have found a solution, here is the code:
new JPAQuery<Car>(em)
.select(car)
.distinct()
.from(car)
.leftJoin(car.owners, owner).fetchJoin()
.where(car.make.eq(make))
.orderBy(new OrderSpecifier<>(Order.ASC, car.id))
.fetch();
I had the same problem and i had to change new JPAQuery(em) to new JPAQuery<Foo>(em)

Linq To Entities 'Only primitive types or enumeration types are supported' Error

I am using LinqPad to test my query. This query works when the LInqPad connection is to my database (LInq to SQL) but it does not work when I change the connection to use my Entity Framework 5 Model.dll. (Linq to Entity). This is in C#.
I have two tables called Plan and PlanDetails. Relationship is one Plan to many PlanDetails.
var q = from pd in PlanDetails
select new {
pd.PlanDetailID,
ThePlanName = (from p in this.Plans
where p.PlanID == pd.PlanID
select p.PlanName)
};
var results = q.ToList();
q.Dump(); //This is a linqpad method to output the result.
I get this error "NotSupportedException: Unable to create a constant value of type 'Domain.Data.Plan'. Only primitive types or enumeration types are supported in this context." Any ideas why this only works with Linq to SQL?
basically it means you are using some complex datatype inside the query for comparison.
in your case i suspect from p in this.Plans where p.PlanID == pd.PlanID is the culprit.
And it depends on DataProvider. It might work for Sql Data Provider, but not for SqlCE data Provider and so on.
what you should do is to convert your this.Plans collection into a primitive type collection containing only the Ids i.e.
var integers = PlanDetails.Plans.Select(s=>s.Id).ToList();
and then use this list inside.
var q = from pd in PlanDetails
select new {
pd.PlanDetailID,
ThePlanName = (from p in integers
where p == pd.PlanID
select pd.PlanName)
};
I got this error when i was trying to null check for a navigational property in the entity framework expression
I resolved it by not using the not null check in the expression and just using Any() function only.
protected Expression<Func<Entities.Employee, bool>> BriefShouldAppearInSearchResults(
IQueryable<Entities.Employee> briefs, string username)
{
var trimmedUsername = NameHelper.GetFormattedName(username);
Expression<Func<Entities.Employee, bool>> filterExpression = cse =>
cse.Employee.Cars.All(c =>
c.Employee.Cars!=null && <--Removing this line resolved my issue
c.Employee.Cars.Any(cur => cur.CarMake =="Benz")));
return filterExpression;
}
Hope this helps someone!
This is a Linqpad bug if you like (or a peculiarity). I found similar behaviour myself. Like me, you may find that your query works with an ObjectContext, but not a DbContext. (And it works in Visual Studio).
I think it has to do with Linqpad's inner structure. It adds MergeAs (AppendOnly) to collections and the context is a UserQuery, which probably contains some code that causes this bug.
This is confirmed by the fact that the code does work when you create a new context instance in the Linqpad code and run the query against this instance.
If the relationship already exists.
Why not simply say.
var q = from pd in PlanDetails
select new {
pd.PlanDetailID,
ThePlanName = pd.Plan.PlanName
};
Of course i'm assuming that every PlanDetail will belong to a Plan.
Update
To get better results from LinqPad you could tell it to use your own assembly (which contains your DbContext) instead of the default Datacontext it uses.

JOINING a ActivityParty Field

I am trying to query data in CRM 2011 and I need to join an ActivityParty. I can't seem to find any good documentation on it. Has anyone done this before. This is my query so far:
var linqQuery = (from r in gServiceContext.CreateQuery("campaignresponse")
join c in gServiceContext.CreateQuery("contact") on ((EntityReference)r["customer"]).Id equals c["contactid"] into opp
join a in gServiceContext,CreateQuery("lead") on ((EntityReference)r["customer"]).Id equals c["leadid"] into opp
from o in opp.DefaultIfEmpty()
where ((EntityReference)r["new_distributorid"]).Id.Equals(lProfileProperty.PropertyValue) && ((OptionSetValue)r["new_distributorstatus"]).Equals("100000002")
select new
{ }
So if you look at the query what I am trying to do is join the contact Entity and the lead Entity to CamapaignResponse via the customer field and the customer field is an ActivityParty field. Any ideas on how to do this? Thanks!
I'm having a hard time figuring out how your query is supposed to work, but I can tell you that you'll have an easier time if you generate Linq entities using the SDK. Then, instead of
from r in gServiceContext.CreateQuery("campaignresponse") where ...
you can just write
gServiceContext.CampaignResponseSet
.Where(cr => cr.property == value)
.Select(cr => new {cr, cr.childObject});
and so forth. You'll get strong typing and IntelliSense, too.

How do I get a Distinct list to work with EF 4.x DBSet Context and the IEqualityComparer?

I have been trying for hours to get a Distinct to work for my code.
I am using EF 4.3, MVC3, Razor and trying to get a list downto product id and name.
When I run the Sql query against the DB, it's fine.
Sql Query is
SELECT DISTINCT [ProductId]
,[Product_Name]
FROM [dbo].[PRODUCT]
The only other column in that table is a country code so that's why a standard distinct() isn't working.
I have gone as far as creating an IEqualityComparer
Here is code:
public class DistinctProduct : IEqualityComparer<PRODUCT>
{
public bool Equals(PRODUCT x, PRODUCT y)
{
return x.ProductId.Equals(y.ProductId);
}
public int GetHashCode(PRODUCT obj)
{
return obj.ProductId.GetHashCode();
}
}
here is where I called it.
IEqualityComparer<PRODUCT> customComparer = new DistinctProduct();
IEnumerable<PRODUCT> y = db.PRODUCTs.Distinct(customComparer);
But when it hit's that Last line I get an error out of it stating...
LINQ to Entities does not recognize the method 'System.Linq.IQueryable`1[MyService.Models.PRODUCT] Distinct[PRODUCT](System.Linq.IQueryable`1[MyService.Models.PRODUCT], System.Collections.Generic.IEqualityComparer`1[MyService.Models.PRODUCT])' method, and this method cannot be translated into a store expression.
Can anyone tell me what I'm doing wrong?
Thanks,
David
Is there any reason you could just not use a distinct like the following?
var distinctProdcts = (from p in db.PRODUCTs
select new {
ProductId = p.ProductId,
Product_Name = p.ProductName
}).Distinct();
This would remove the country code from the query before you do the distinct.
Entity Framework is trying to translate your query to a SQL query. Obviously it does not know how to translate the IEqualityComparerer. I think the question is whether you want to do the Distinct in the datbase (in which case your client gets only filtered results) or you are OK with bringing all the data to the client and select distinct on the client. If you want the filtering to happen on the database side (which will make your app perform much better) and you want to be able to use different strategies for comparing you can come up with a code that builds distinct criteria on top of your query. If you are fine with bringing your data to the client (note that it can be a lot of data) you should be able just to do (.ToList() will trigger querying the database and materializing results):
IEnumerable<PRODUCT> y = db.PRODUCTs.ToList().Distinct(customComparer);

Entity Framework 4.1 Link table query how to?

I'm relatively new to the Entity Framework and I'd like to do a query that includes a link table. Any suggestions on how to do a basic join query using LINQ?
Entity Structure
News
NewsID
CommunityNews
CommunityID
NewsID
Community
CommunityID
If you're generating the context from a database using the EDMX editor, and you have the appropriate foreign key constraints set up, you should be able to just add those three tables to the context, and it will create a many-to-many mapping between News and Community.
var newsForCommunity = context.News.Where(
n => n.Communities.Any(
c => c.CommunityId == communityId);
Here is another way you can write the query:
var newsForCommunity =
(from c in context.Communities
from n in c.News
where c.CommunityID == communityID
select n.NewsID
).ToList();

Resources