Linq query which has a non db object within - linq

I have multiple View Model classes that get data from the database using Linq (DBContext classes have a similar structure but with more fields)
I am lacking knowledge to get data from one class object because that is contained within a wrapper class that does not have a corresponding db object.
Thank you in advance for any help or suggestions on this.
Here are the class structures:
public class TopLevelViewModel
{
public TopLevelID { get; set; }
public TopLevelTitle { get; set; }
public List<SecondLevelViewModel> SeconLevel { set; get; }
public TopLevelViewModel()
{
Inner = new List<SecondLevelViewModel>();
}
}
public class SecondLevelViewModel
{
public SecondLevelID { get; set; }
public SecondLevelTitle { get; set; }
public TopLevelID { get; set; }
public WrapperViewModel { get; set; }
}
public class InnerViewModel
{
public InnerID { get; set; }
public InnerTitle { get; set; }
public SecondLevelID { get; set; }
}
public class WrapperViewModel
{
public List<InnerViewModel> Inner { set; get; }
public WrapperViewModel()
{
Inner = new List<InnerViewModel>();
}
}
Linq query to get data for the above db objects:
List<TopLevelViewModel> data = null;
data = db.TopLevel.Where(t => t.TopLevelID == URLTopLevelID)
.Select(t => new TopLevelViewModel()
{
TopLevelID = t.TopLevelID,
TopLevelTitle = t.TopLevelTitle,
SeconLevel = db.SecondLevel.Where(s => s.TopLevelID == t.TopLevelID)
.Select(s => new SecondLevelViewModel()
{
SecondLevelID = s.SecondLevelID,
SeconLevelTitle = s.SeconLevelTitle,
WrapperViewModel = ???
}).ToList<SecondLevelViewModel>()
}).ToList < TopLevelViewModel();
Query to get Inner object data:
db.Inner.Where(i => i.SecondLevelID == s.SecondLevelID)
.Select(i => new InnerViewModel()
{
InnerID = i.InnerID,
InnerTitle = i.InnerTitle
}).ToList<InnerViewModel>()
Question: how do I incorporate the above inner query to be part of WrapperViewModel class and have that in the main Linq query as a single query?
WrapperViewModel does not have a DB object but it is kind of a wrapper class to InnerViewModel class.

I think I figured it out. Hope it will be useful to someone. If there are any ideas/suggestions please share!
The single query would be:
List<TopLevelViewModel> data = null ;
data = db.TopLevel.Where(t => t.TopLevelID == URLTopLevelID).Select(t => new TopLevelViewModel()
{
TopLevelID = t.TopLevelID,
TopLevelTitle = t.TopLevelTitle,
SeconLevel = db.SecondLevel.Where(s => s.TopLevelID == t.TopLevelID).Select(s => new SecondLevelViewModel()
{
SecondLevelID = s.SecondLevelID,
SeconLevelTitle = s.SeconLevelTitle,
WrapperViewModel = new WrapperViewModel { Inner =
db.Inner.Where(i => i.SecondLevelID == s.SecondLevelID).Select(i => new InnerViewModel()
{
InnerID = i.InnerID,
InnerTitle = i.InnerTitle
}).ToList<InnerViewModel>()
}).ToList<SecondLevelViewModel>()
}).ToList < TopLevelViewModel();

Related

How to select 2 objects from 2 tables in one query?

I want to get the below result in one query by linq methods such as .Where, .Select etc., is it possible?
Inner join is the better.
new {
Blog = MyDbContext.Blogs.SingleOrDefault(b => b.Url == "xxx.com"),
Post = MyDbContext.Posts.SingleOrDefault(p => p.Blog.Url == "xxx.com" &&
p.Author == "Jack")
}
Models:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Author { get; set; }
public Blog Blog { get; set; }
}
public class MyDbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
var ans = MyDbContext.Blogs.Where(b => b.Url == "xxx.com")
.Select(b => new {
Blog = b,
Post = b.Posts.Where(p => p.Author == "Jack").FirstOrDefault()
})
.SingleOrDefault();

SQl to Linq query- subquery with datetime

I would like to know the LINQ for this SQL.Appreciate any help
select Value FROM GPUD where param ='RVOUTc'
and dateandtime in (select max(b.dateandtime) from GPUD as b where b.param= 'rvoutc'and convert(date,getdate()) = convert(date,b.DateAndTime)
group by b.param )
Did not test it, but it should get you started, good luck.
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var GPUDCollection = new List<GPUD>();
var maxDate = GPUDCollection.
Max(gpud => gpud.dateandtime.Date);
var result = GPUDCollection.
Where(gpud => gpud.Param.Equals("rvoutc") && gpud.dateandtime.Date.Equals(maxDate)).
Select(gpud => gpud.Value);
}
}
public class GPUD
{
public DateTime dateandtime { get; set; }
public string Param { get; set; }
public object Value { get; set; }
}

Linq query to find matches in nested lists

Using the classes below I need to select items from AllMeta where there is a match in Meta.
The match criteria is that at least 1 group in Meta.Groups.Name matches that of AllMeta.Values.Groups.Name.
AllMeta: is a dictionary<string, WikiMeta>
Meta: is a WikiMeta
public class WikiMeta
{
public string ContentTitle { get; set; }
public string PageTitle { get; set; }
public string PageMetaDescription { get; set; }
public List<WikiArticle> Articles = new List<WikiArticle>();
public List<WikiGroup> Groups = new List<WikiGroup>();
}
public class WikiGroup
{
public string Name { get; set; }
}
Any help appreciated.
A nested Any is the direct approach:
var result = AllMeta
.Where(kv =>
Meta.Any(m =>
m.Groups.Any(mg =>
kv.Value.Groups.Any(vmg =>
vmg.Name == mg.Name))));
Apologies Tim, slight error in specification. Meta is a single
WikiMeta but with one or more Groups.
var result = AllMeta
.Where(kv => Meta.Groups.Any(mg => kv.Value.Groups.Any(vmg => vmg.Name == mg.Name)));

LINQ - Combine multiple lists to form a new list and align them by key?

I have two list of different columns, but each list have a common column with the same key, how do I combine them into a new list, i.e:
public class TradeBalanceBreak
{
public int CommID { get; set; }
public int CPFirmID { get; set; }
public double CreditDfferenceNotional { get; set; }
public string Currency { get; set; }
}
public class Commission
{
public int CommID { get; set; }
public PeriodStart { get; set; }
public ResearchCredit { get; set; }
}
public class CommissionList
{
public List<Commission> Commissions { get { return GetCommissions(); }}
private List<Commission> GetCommissions()
{
// retrieve data code ... ...
}
}
public class TradeBalanceBreakModel
{
public List<TradeBalanceBreak> TradeBalanceBreaks { get; set; }
}
public class CommissionModel
{
public List<CommissionList> CommissionLists { get; set; }
}
What I would like to achieve is to combine/flatten the TradeBalancesBreaks and CommissionLists (from the model classes) into one. The CommID is shared between the two.
Thanks.
Using Join (extension method version) -- after your update
var list1 = GetTradeBalanceBreaks();
var list2 = new CommisionsList().Commissions;
var combined = list1.Join( list2, l1 => l1.ID, l2 => l2.First().ID,
(l1,l2) = > new
{
l1.CommID,
l1.CPFirmID,
l1.CreditDifferenceNotional,
l1.Currency,
PeriodStarts= l2.SelectMany( l => l.PeriodStart ),
ResearchCredits = l2.SelectMany( l => l.ResearchCredit )
})
.ToList();
var combined = from p in PhoneNumbers
join a in Addresses on a.ID equals p.ID
select new {
ID = p.ID,
Name = p.Name,
Phone = p.Phone,
Address = a.Address,
Fax = a.Fax
};

Linq to entities: cast result to multiple listed complex types

I'm trying to create a single linq query which populates the following models in the CompanyViewModel constructor:
public class CompanyViewModel
{
public IList<CompanyUserViewModel> CompanyUsers { get; set; }
...
}
public class CompanyUserViewModel
{
public User User { get; set; }
public IList<UserOperationViewModel> UsersOperations { get; set; }
}
public class UserOperationViewModel
{
public Operation Operation { get; set; }
public int Permission { get; set; }
}
Currently I've got the following query:
return db.Users.Where(u => u.CompanyId == companyId)
.Select(u => new CompanyUserViewModel {
User = u,
UsersOperations = db.UsersInOperations
.Where(uo => uo.UserId == uo.UserId)
.Select(uo => new UserOperationViewModel{
Operation = uo.Operation,
Permission = uo.Permission
}).ToList()
}).ToList();
Which builds, but when the page runs I get
LINQ to Entities does not recognize the method 'System.Collections.Generic.List`1[WoodCo.Models.BusinessObject.UserOperationViewModel] ToList[UserOperationViewModel](System.Collections.Generic.IEnumerable`1[WoodCo.Models.BusinessObject.UserOperationViewModel])' method, and this method cannot be translated into a store expression.
What does one do?
Change your view model properties to use IEnumerable<T> instead of IList<T and remove the .ToList() calls.

Resources