error when converting linq lambda query to list - c#

i am trying to query data using linq, i am joining two tables where id == to id of the second table. i am getting an exception error saying
Cannot implicitly convert type
'System.Collections.Generic.List<AnonymousType#1>' to
'System.Collections.Generic.List<--db table here-->'.
var qry = context.Projects
.Join(context.Members, p => p.ID, m => m.ID, (p, m) => new { p, m })
.Where(u => u.m.ID == memId)
.Select(b => new {
b.p.ProjName,
b.p.ProjDesc,
b.p.ProjectType,
b.p.Tags
});
return qry.ToList();

You are trying to return a list of anonymous type from your method but the return type is probably something like List<SomeType>.
So instead of creating anonymous objects you need to create objects of your type.
.Select(b => new SomeType {
// set properties here
});

Related

C# Linq Unable to create a constant value of type 'System.Object'. Only primitive types or enumeration types are supported in this context

I know that there're some similar questions to this one, but I'm not being able to fix my issue.
I have the following method:
public IDictionary<string, int> CountXXX(Expression<Func<MessageStatus, bool>> whereFilter = null)
{
try
{
var trackingOpens = whereFilter != null ? _context.MessageStatus.Where(whereFilter).Join(_context.TrackingOpens, x => x.MessageId, g => g.MessageId, (x, g) => x) :
_context.MessageStatus.Join(_context.TrackingOpens, x => x.MessageId, g => g.MessageId, (x, g) => x);
return trackingOpens
.GroupBy(x => x.VariationId)
.Select(g => new { Variation = g.Key.ToString(), Count = g.Count() })
.ToDictionary(x => x.Variation, x => x.Count);
}
catch (Exception e)
{
throw new Exception($"There's been an error trying to count the tracking opens from the database. Details: {e.Message}", e);
}
}
I have the class MessageStatus with VariationId property, I need to group them and count for each one. The problem is that I need to Join with TrackingOpens on MessageId. The Linqstatement here is returning the exception mentioned on the title.
The whereFilter parameter is just another Linq statement that goes inside the .where clause.
TrackingOpens does not have the field VariationId and I cannot add it to that model
Can anyone help me fix this Linq statement?

How to create a linq lambda join query that pulls results even though there null results?

I have this join query that pulls all school programs and products that is in a person's shopping cart:
//this pulls all items the user purchased
var poop = Context.Query<Cart>().Where(x => x.UserId == currentUserId && x.Status == "Archived")
.Select(
p => new
{
p.ItemId,
p.TypeId,
p.PurchaseDate
})
//This get the media type name of the cart items
.Join(
Context.Query<MediaType>(),
t => new {t.TypeId},
m => new {TypeId = m.Id},
(t, m) => new
{
t.ItemId,
t.TypeId,
t.PurchaseDate,
m.TypeName
}).OrderBy(d => d.PurchaseDate)
//Now i need specifics of the items like name, sku, etc. StartDate will be null for items that are products, but contains DateTime for items that are programs.
.Join(
Context.Query<ProgramProductView>(),
e => new {e.ItemId, e.TypeId},
prog => new {ItemId = prog.Id, prog.TypeId},
(e, prog) => new
{
e.ItemId,
e.TypeId,
e.PurchaseDate,
e.TypeName,
prog.FullName,
prog.StartDate,
prog.Sku,
prog.Closed
}).OrderBy(d => d.PurchaseDate);
So right there is where it crashes because prog.StartDate is null for products. I get SQL is not available error.
Is there a way to have the join allow null-able fields? I am only using lambda because it's easier to read and clean.
Well you just need to use Nullable<> property for you anonymous class in your last Join:
.Join(
Context.Query<ProgramProductView>(),
e => new {e.ItemId, e.TypeId},
prog => new {ItemId = prog.Id, prog.TypeId},
(e, prog) =>
new
{
...
(DateTime?)prog.StartDate,
...
}).OrderBy(d => d.PurchaseDate);
Hope it will help.

How to modify the argument of the GroupBy() method?

This is my a linq query that filter tasks by range name then group them by language.
var transTasks = taskData
.Where(t => t.RangeName == rName)
.GroupBy(t => t.CultureID)
.Select(g => new { language = g.Key, tasks = g });
Now I'd like to use the same query for a different grouping. Instead of grouping by CultureID, I'd like to group by TaskOrder.
So I've create variables like this
Func<QuoteTaskInfo, bool> predicate = null
if(tasktype == "translation")
{
groupPredicate = t => t.CultureID;
{
else
{
groupPredicate = t => t.TaskOrder;
}
I'm getting the following error: "Cannot convert expression ... because some return type are not convertible to the delegate return type".
Any help on how to write a delegate that would return a bool?
The same goes with Select(). If the criteria is task order, then the key for the select should be TaskOrder instead of language.
Thanks for helping

How can I group by Linq statement

How can I group by this linq statement?
public IQueryable<Lottery> GetLotteriesByLotteryOfferId(int lotteryOfferId)
{
return this.db.LotteryOffers
.Where(lo => lo.Id == lotteryOfferId)
.SelectMany(lo => lo.LotteryDrawDates)
.Select(ldd => ldd.Lottery);
}
This doesn't work:
public IQueryable<Lottery> GetLotteriesByLotteryOfferId(int lotteryOfferId)
{
return this.db.LotteryOffers
.Where(lo => lo.Id == lotteryOfferId)
.SelectMany(lo => lo.LotteryDrawDates)
.Select(ldd => ldd.Lottery)
.GroupBy(s => new { s.Name, s.CreatedBy, s.ModifiedOn, s.Id })
.Select(g => new Lottery
{
Name = g.Key.Name,
CreatedBy = g.Key.CreatedBy,
ModifiedOn = g.Key.ModifiedOn,
Id = g.Key.Id
});
}
Error that I get:
The entity or complex type 'Lottery' cannot be constructed in a LINQ
to Entities query.
I use data service(web service).
LINQ to SQL and LINQ to Entities - unlike LINQ to Objects and LINQ to Xml - uses the higher order methods to generate SQL that will be ran on the database, and therefore the lambdas don't have the full power of the language. Creating a new Lottery in the Select "clause" makes no sense - you don't want to create those Lottery objects in the database process, you want to create them in your application's process.
What you need to do is to use AsEnumerable:
return this.db.LotteryOffers
.Where(lo => lo.Id == lotteryOfferId)
.SelectMany(lo => lo.LotteryDrawDates)
.Select(ldd => ldd.Lottery)
.GroupBy(s => new { s.Name, s.CreatedBy, s.ModifiedOn, s.Id })
.AsEnumerable()
.Select(g => new Lottery
{
Name = g.Key.Name,
CreatedBy = g.Key.CreatedBy,
ModifiedOn = g.Key.ModifiedOn,
Id = g.Key.Id
});
Everything before the AsEnumerable generates SQL. The call to AsEnumerable forces C# to execute the query and get the result as a stream of objects - something that Select can now use to generate your Lottery objects.

Is it possible to use Select(l=> new{}) with SelectMany in EntityFramework

I am trying something that i not really sure but i want to ask here if it s possible.
Is it able to be done ?
public IQueryable<Info> GetInfo(int count, byte languageId)
{
return db.Info.SelectMany(i => i.LanguageInfo)
.Where(l => l.Language.id == languageId)
.Select(l => new Info { AddDate = l.Info.AddDate,
Description = l.Description,
EntityKey = l.Info.EntityKey,
id = l.Info.id,
Title = l.Title,
ViewCount = l.Info.ViewCount }
)
.OrderByDescending(i => i.id)
.Take(count);
}
When this method is executed i got an error
The entity or complex type
'GuideModel.Info' cannot be
constructed in a LINQ to Entities
query.
Does it mean "not possible" ?
Thank you
The error essentially indicates that the Entity Framework doesn't know how to create an Info object, since it is not bound to a table object. (Put another way, the Select call on the IQueryable cannot be translated into equivalent SQL.) You could perform the Select projection on the client via:
public IQueryable<Info> GetInfo(int count, byte languageId)
{
return db.Info.SelectMany(i => i.LanguageInfo)
.Where(l => l.Language.id == languageId)
.Take(count)
.AsEnumerable()
.Select(l => new Info { AddDate = l.Info.AddDate,
Description = l.Description,
EntityKey = l.Info.EntityKey,
id = l.Info.id,
Title = l.Title,
ViewCount = l.Info.ViewCount }
)
.OrderByDescending(i => i.id);
}
It is possible to use Select(l => new ...), but not with an Entity type. You need to use an anonymous type or a POCO type with a parameterless constructor. Entity types are "special" because of the way they interact with the ObjectContext. You can select them, but not new them up in a query.
The code below worked for me. Here "SearchTerm" is a complex type. Thanks Jason :)
var lstSynonym = TechContext.TermSynonyms
.Where(p => p.Name.StartsWith(startLetter))
.AsEnumerable()
.Select(u => new SearchTerm
{
ContentId = u.ContentId,
Title = u.Name,
Url = u.Url
});

Categories