I am trying to convert this T-SQL to a Linq To SQL but can't work out the group by aggregate functions. Any help welcome.
select c.ClientID, GivenName, Surname, max(a.Address), max(t.Value)
from Client c
left join ClientAddress a on c.ClientID = a.ClientID
left join ClientContact t on c.ClientID = t.ClientID
group by c.ClientID, GivenName, Surname
To group by a composite key, you typically use an anonymous type:
var qry = from x in someSource
group x by new { x.ClientID, x.GivenName, x.Surname } into grp
select new { grp.Key, Address = grp.Max(x => x.Address),
Value = grp.Max(x => x.Value) };
The exact answer I came up with was
public IQueryable<ClientSearchDTO> GetClientsDTO()
{
return (from client in this.Context.Clients
join address in this.Context.ClientAddresses on client.ClientID equals address.ClientID
join contact in this.Context.ClientContacts on client.ClientID equals contact.ClientID
where contact.ContactType == "Phone"
group client by new { client.ClientID, client.Surname, client.GivenName } into clientGroup
select new ClientSearchDTO()
{
ClientID = clientGroup.Key.ClientID,
Surname = clientGroup.Key.Surname,
GivenName = clientGroup.Key.GivenName,
Address = clientGroup.Max(x => x.ClientAddresses.FirstOrDefault().Address),
PhoneNumber = clientGroup.Max(x => x.ClientContacts.FirstOrDefault().Value)
});
}
Related
How can I avoid multiple calls to repositories and simplify using joins?
var members = await _groupMemberRepository.Value.GetAllGroupMembers(groupId);
var groupMemberModels = members as IGroupMemberModel[] ?? members.ToArray();
var users = await _userManager.Value.GetUsersList(groupMemberModels.Select(x => x.UserId));
var roles = await _userAccountBusinessLogic.GetRoles(null);
return (from m in groupMemberModels
join u in users
on m.UserId equals u.Id
select
new Member
{
UserId = m.UserId,
FirstName = u.FirstName,
LastName = u.LastName,
Username = u.UserName,
GroupUserType = m.GroupUserType,
LastLoggedIn = u.LastLoggedIn,
Roles = MeeRoleParser.ParseList(u.Roles.Select(x =>
roles.Where(r => r.Id == x.RoleId).Select(r => r.Name).FirstOrDefault()).ToList())
}).ToArray();
The above query calls different repositories. I am not getting an idea how to do a join and simplify the call
I have a 3 tables Dish, Wine, Suggestion.
Then the idea is use table suggestion table to put the dish and the wine making one of them suggestion each other.
I'm using LINQ, but when one product doesn't have a suggestion he does not add to the json.
var query = (from m in db.Dish
join t in db.TypeDish on m.idTypeDish equals t.idTypeDish
join i in db.ImageDish on m.idDish equals i.idDish into g
join s in db.Suggestion on m.idDish equals s.idDish
join si in db.ImageWine on s.idWine equals si.idWine into f
where m.idTypeDish == dish
select new DishModel()
{
Name = m.name,
CalorificValue = m.calorificValue,
Price = m.price,
ShortName = m.shortName,
Time = m.manufactureTime,
Description = m.description,
UrlImageList = g.Select(i => _url + i.Image.urlImage).ToList(),
BeveragesList = new List<BeverageModel>()
{
new BeverageModel()
{
Name = s.Wine.name,
ShortName = s.Wine.shortName,
Price = s.Wine.price,
Description = s.Wine.description,
AlcoholContent = s.Wine.alcoholContent,
WineEnum = WineEnum.WhiteWine,
Region = s.Wine.Region.name,
WineCaste = s.Wine.wineCaste,
UrlImageList = f.Select(i => _url+i.Image.urlImage).ToList(),
}
}
}).ToList();
return query;
Now I have 2 items on DB, and he sends only one because the other don't have a suggestion.
The error is on joins probably, but I'm a newbie in Linq.
Thanks.
I am trying to pass data from a view model which derives from 2 models. The controller looks like this
public ActionResult SessionDetails()
{
var Sessions = (from a in db.Appointments
join c in db.Clients
on a.clientid equals c.id into SessionList
from c in SessionList.DefaultIfEmpty()
select new SessionViewModel()
{
id = a.id,
sessionnotes = a.sessionnotes,
firstname = c.firstname,
date = a.date,
}).ToList()
.Select(x => new SessionViewModel()
{
id = a.id,
sessionnotes = a.sessionnotes,
firstname = c.firstname,
date = a.date,
});
return View(Sessions);
}
It is coming up with errors saying the name "a" does not exist in the current context? Any ideas as to what is going on?
I am really new to this, I followed these instructions using website http://techfunda.com/howto/262/list-data-using-viewmodel which does what I want SessionDetails to do.
I already have a view for this.
UPDATE
I have made following changes:
public ActionResult SessionDetails()
{
var Sessions = (from a in db.Appointments
join c in db.Clients
on a.clientid equals c.id into SessionList
from c in SessionList.DefaultIfEmpty()
select new SessionViewModel()
{
id = a.id,
sessionnotes = a.sessionnotes,
firstname = c.firstname,
date = a.date,
}).ToList();
return View(Sessions);
}
But when i run it, i get this: an exception of type System.NotSupportedException occurred in EntityFramework.SqlServer.dll but was not handled in user code.
Additional information: the entity or complex type fypag.Models.SessionViewModel cannot be constructed in a LINQ to Entities query.
I think your model should look like this.
var Sessions = (from a in db.Appointments
join c in db.Clients
on a.clientid equals c.id into SessionList
from c in SessionList.DefaultIfEmpty()
select new SessionViewModel()
{
id = a.id,
sessionnotes = a.sessionnotes,
firstname = c.firstname,
date = a.date,
}).ToList()
.Select(x => new SessionViewModel()
{
id = x.id,
sessionnotes = x.sessionnotes,
firstname = x.firstname,
date = x.date,
});
UPDATE:
var Sessions = (from a in db.Appointments
join c in db.Clients
on a.clientid equals c.id into SessionList
from c in SessionList.DefaultIfEmpty()
.Select(y => new SessionViewModel()
{
id = y.id,
sessionnotes = y.sessionnotes,
firstname = y.firstname,
date = y.date,
}).ToList();
I'm trying to do a left join in an EF query. I'm getting the following error:
Error CS1941 The type of one of the expressions in the join clause is
incorrect. Type inference failed in the call to 'GroupJoin'
and here is the C# code:
var foo = from m in db.ClientMasters
join a in db.Orders on new { m.Id, Status = "N" } equals new { a.ClientID, a.Status } into a_join
from a in a_join.DefaultIfEmpty()
select new { m.ClientID, a.ID };
The column names have to match in the join; here is the corrected code:
var foo = from m in db.ClientMasters
join a in db.Orders on new { ClientID = m.Id, Status = "N" } equals new { a.ClientID, a.Status } into a_join
from a in a_join.DefaultIfEmpty()
select new { ClientID = m.Id, OrderId = a.Id };
New to MVC, Checked lot of workarounds.. didn't help:
This code is written in model repository, which returns a list that I can return to View(Index)
IList<AccessArticles> publisherList = (from aa in db.AccessArticles
join u in db.Users on aa.UserId equals u.id
join a in db.Articles on aa.ArticleId equals a.id
where u.id == id
orderby a.title
select new
{
UserName = u.username,
ArticleTitle = a.title,
AccessArticlesId = aa.AccessArticlesId,
ArticleId = aa.ArticleId,
UserId = aa.UserId
})
.AsEnumerable()
.Select
(x=> new AccessArticles
{
AccessArticlesId = x.AccessArticlesId,
UserId = x.UserId,
UserName = x.UserName,
ArticleTitle = x.ArticleTitle
}).ToList();
Error that I get is Specified cast is not valid.
Please suggest a wayout or a better way to get the same effect.
Thanks
Code reference -
Interface :
List<AccessArticles> SearchByUserId(int UserId);
Repository :
public List<AccessArticles> SearchByUserId(int id)
{
var setArticles = (from aa in db.AccessArticles
join u in db.Users on aa.UserId equals u.id
join a in db.Articles on aa.ArticleId equals a.id
where u.id == id
orderby a.title
select new AccessArticles
{
UserName= u.username,
ArticleTitle = a.title,
AccessArticlesId= aa.AccessArticlesId,
ArticleId = aa.ArticleId,
UserId = aa.UserId
}).ToList();
return setArticles;
}
Controller
public ActionResult Index(int? id)
{
int UserId = 0;
if (id != null)
{
UserId = Convert.ToInt32(id);
}
IAccessArticlesRepository AccessRepository = new AccessArticlesRepository();
//int count = AccessRepository.SearchByUserId(UserId).Count();
List_AccessArticles = AccessRepository.SearchByUserId(UserId);
return View(List_AccessArticles);
}
Model
namespace theSiteCMS.Models
{
public partial class AccessArticles
{
public string ArticleTitle { get; set; }
public string UserName { get; set; }
}
}
I did some changes taking some reference:
----------
Repository
----------
public IQueryable<AccessArticles> SearchByUserId(int id)
{
var setArticles = (from aa in db.AccessArticles
join u in db.Users on aa.UserId equals u.id
join a in db.Articles on aa.ArticleId equals a.id
where u.id == id
orderby a.title
select new AccessArticles
{
UserName= u.username,
ArticleTitle = a.title,
AccessArticlesId= aa.AccessArticlesId,
ArticleId = aa.ArticleId,
UserId = aa.UserId
});
return setArticles;
}
--------------
Controller
--------------
public ActionResult Index(int? id)
{
int UserId = 0;
if (id != null)
{
UserId = Convert.ToInt32(id);
}
IAccessArticlesRepository AccessRepository = new AccessArticlesRepository();
var userwisearticles = AccessRepository.SearchByUserId(UserId);
return View(userwisearticles);
}
Error:
In Index.aspx page:
<% foreach (var item in Model) { %>
Highlight on 'Model' - Explicit construction of entity type 'theSiteCMS.Models.AccessArticles' in query is not allowed.
This returns a collection of Anonymous types with the properties described below. If you need to use an existing class, make sure it's not the one your EF is using to represent your entity unless it matches directly. If that's the case, then you should be able to to replace the select new below with select aa and have it return a list of the entity models that EF built for you.
var publisherList = (from aa in db.AccessArticles
join u in db.Users on aa.UserId equals u.Id
join a in db.Articles on aa.ArticleId equals a.Id
where u.Id == userId
orderby a.Title
select new
{
UserName = u.UserName,
ArticleTitle = a.Title,
AccessArticleId = aa.AccessArticlesId,
UserId = aa.UserId
}).ToList();
Edited to select the EF entity directly;
var publisherList = (from aa in db.AccessArticles
join u in db.Users on aa.UserId equals u.Id
join a in db.Articles on aa.ArticleId equals a.Id
where u.Id == userId
orderby a.Title
select aa).ToList();
That should trigger a compile error because your return type doesn't match. I'm guessing it has to be List<AccessArticle>