Spliton in Dapper, ASP NET Core - asp.net-mvc

string query = #"SELECT
l.LoginId,
l.Email,
un.UserNameId,
un.Name,
un.CPF,
un.CellPhone,
ga.GroupId,
ga.Name
FROM Tb_Login l
INNER JOIN Tb_UserName un
ON un.IdLogin = l.LoginId
INNER JOIN Tb_GroupAccess ga
ON ga.GroupId = l.IdGroupAccess
WHERE un.IdLogin = #Id
AND l.IdStatusLogin = 1";
var obj = _connection.Query<EmployeeResponse, Login, UserName, GroupAccess, EmployeeResponse>(
sql: query,
map: (loginResponse, login, userName, groupAcess) =>
{
loginResponse.Login = login;
loginResponse.UserName = userName;
loginResponse.GroupAccess = groupAcess;
return loginResponse;
},
splitOn: "UserNameId,GroupId",
param: new
{
Id = request.IdEmployee
}
).FirstOrDefault();
This code is returning:
System.ArgumentException: 'Multi-map error: splitOn column 'UserNameId' was not found - please ensure your splitOn parameter is set and in the correct order Arg_ParamName_Name'
I'm having problems trying to do this spliton.

As I stated in my comment: The first EmployeeResponse in the query shouldn't be there. It should say _connection.Query<Login, UserName, GroupAccess, EmployeeResponse> meaning: Map to Login, UserName and GroupAccess, return an EmployeeResponse. There is nothing in the query that can be mapped directly to EmployeeResponse
Therefore you also need to create the employee response yourself, so the code becomes something like:
var obj = _connection.Query<Login, UserName, GroupAccess, EmployeeResponse>(
sql: query,
map: (login, userName, groupAccess) =>
{
return new EmployeeResponse {
Login = login;
UserName = userName;
GroupAccess = groupAccess};
},
splitOn: "UserNameId,GroupId",
param: new
{
Id = request.IdEmployee
}
).FirstOrDefault();

Related

A better way to combine two Linq Queries into one in MVC5 Controller

in my MVC Application using EntityFramework I have a self referencing table: customers with customerParentID. For children with no emails I want to be able to channel correspondence to parents Email. This is the solution I have that works but I am hitting database 3 times and I want to combine the last 2 into one.
Controller Linq Query
useParentEmail is a bool which is true for children with no Email
Id is obtained by a parameter
var b = db.Lists.SingleOrDefault(a => a.LatestTxnId == Id);
var customerWithNoEmail = db.Customers.SingleOrDefault(a => a.CustomerID == b.CustomerID && a.useParentEmail);
if (customerWithNoEmail != null)
{
var customerParent = db.Customers.SingleOrDefault(a => a.CustomerID == customerWithNoEmail.ParentCustomerID);
customerParentEmail = customerParent.Email;
}
This query hits database twice is there a better way I can do this to hit database once? Any help will be appreciated.
Assuming you are using Entity Framework with the correct navigation properties in the model so that joins work automagically, something like this could work (I've used LinqPad and linq to objects for ease of example). To be honest although I used to be a heavy user of Entity Framework I haven't used it for a few years so I could be a little rusty.
var customers = new[]
{
new { CustomerID = 1, useParentEmail = true, email = "", ParentCustomerID = (int?)2 },
new { CustomerID = 2, useParentEmail = false, email = "parent#example.org", ParentCustomerID = (int?)null },
new { CustomerID = 3, useParentEmail = false, email = "child#example.org", ParentCustomerID = (int?)null }
};
int id = 1;
var emails = (from c in customers
join p in customers on c.ParentCustomerID equals p.CustomerID into childrenParents
from cp in childrenParents.DefaultIfEmpty()
where c.CustomerID == id
select new
{
c.CustomerID,
email = c.useParentEmail == true ? cp.email : c.email
}).SingleOrDefault();
emails.Dump();

When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id

I keep on getting this error. The place where it's throwing the error is:
var projectManagerList = gridReader.Read<ProjectResources, Employee, ProjectResources>((pr, e) =>
{
pr.Employee = e;
return pr;
}).ToList();
The sql is:
SELECT DISTINCT
p_Resources.Empl_ID as EmployeeId
,p_Resources.cRole
,p_Empl.ID as Id
,p_Empl.Title
,p_Empl.First_Name as FirstName
,p_Empl.MI as MiddleInitial
,p_Empl.Last_Name as LastName
,p_Empl.Phone
,p_Empl.PWD as Password
,p_Empl.email as Email
,p_Empl.LoginName
,p_Empl.Admin
FROM p_Empl
LEFT OUTER JOIN
p_Resources on p_Resources.Empl_ID = p_Empl.ID
WHERE p_Resources.cRole='Project Manager'
I wrote "as Id" so why is it throwing the error? Thanks.
It tells you to set the splitOn parameter. So you should set it to Id.
var projectManagerList = gridReader.Read<ProjectResources, Employee,
ProjectResources>((pr, e) =>
{
pr.Employee = e;
return pr;
},splitOn: "Id").ToList();
It tells you the split between ProjectResources and Employee is the Id column.

The name does not exist in the current context (in ActionResult with MVC Entity Framework)

In ActionResult "Details(int? id)" of a controller I have (in ActionResult this is inside of an condition: if (User.Identity.IsAuthenticated) { bla, bla):
var TheUser = db.AspNetUsers.Where(u => u.Id == CurrentUser)
.Select(u => new
{
ID = u.Id,
Email = u.Email,
Username = u.UserName,
Surrname = u.Surname,
Name = u.Name,
Role = u.Role,
CreditBalance = u.CreditBalance
}).Single();
var TheJournal = db.CreditJournal.Where(tj => tj.CvID == id && tj.UseBy == CurrentUser)
.Select(tj => new
{
IdJournal = tj.IdJournal,
Operation = tj.Operation,
CvID = tj.CvID,
CreditConsumed = tj.CreditConsumed,
UseDate = tj.UseDate,
UseBy = tj.UseBy
});
var Counter = TheJournal.Count();
When I evaluate values in Debug Mode I have:
TheUser |>>> { ID = "56cc2430-4db5-4799-ad41-fa1d103d1967", Email = "sales#maps4u.ro", Username = "sales#maps4u.ro", Surrname = "Laurentiu", Name = "LAZAR", Role = 3, CreditBalance = 75 } <Anonymous Type>
TheJournal |>>> {System.Data.Entity.Infrastructure.DbQuery<<>f__AnonymousType9<int,string,int?,int?,System.DateTime?,string>>} System.Linq.IQueryable<<>f__AnonymousType9<int,string,int?,int?,System.DateTime?,string>> {System.Data.Entity.Infrastructure.DbQuery<<>f__AnonymousType9<int,string,int?,int?,System.DateTime?,string>>}
Counter |>>> The name 'Counter' does not exist in the current context
What can be wrong in the simple code shown above? (The equivalent SQL statement for TheJornal returns for the given criteria, at least 4 records).
Somehow I think to declare the variables outside the condition, but what type do they have to be? (Anyway the first, TheUser is just ok, the issue starts with second, TheJournal )
Use .ToList() for your TheJournal query. And then use Count to get the Counter -
var Counter = TheJournal.Count

Can't able to access data by LINQ query

[HttpPost]
public ActionResult Playlist(String ID)
{
long playid=Convert.ToInt64(ID);
var q = from client in Clients
join m in db.Playlists on client.ClientId equals m.ClientId
join meta in db.ContentMetaDatas on m.PlaylistId equals meta.PlaylistId
where m.PlaylistId.Equals(playid)
orderby m.PlaylistId descending
select new SimpleViewModel
{
ID = m.PlaylistId,
Live = false,
Expired = meta.ContentMetaDataExpiryDateTime != null,
Details = m.PlaylistShortDescription,
ImageUrl = meta.ContentMetaDataImage,
Title = m.PlaylistTitle
};
return Json(q.ToPage(p, "ID desc"), JsonRequestBehavior.DenyGet);
}
As shown in the above code of controller I want to fetch data those are returned in JSON data format & used in view.
But As I have to convert the string into long datatype,
what can I do for getting data. Is there anything wrong in the above code??

Problem with Json

Im having this weird problem with creating Json dynamically.... for some reason this doesnt work
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from company in companies
select new
{
i = company.Id,
cell = new string[] { company.Id.ToString(), ""+company.Name.ToString()+"" }
}).ToArray()
};
Its giving me a weird "Could not translate expression....... into sql" exception
but with this minor change it works just fine
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from company in companies
select new
{
i = company.Id,
cell = new string[] { company.Id.ToString(), ""+company.Name.ToString()+"" }
}).ToArray()
};
Notice that the change is just to make id=5 instead of dynamic.
also, this works correctly but I dont like it.
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from company in companies
select new
{
i = company.Id,
cell = new string[] { company.Id.ToString(), ""+company.Name.ToString()+"" }
}).ToArray()
};
I'm not sure if this will solve your problem, but assuming companies is an IQueryable from the DataContext, try calling ToList() on it so that the select expression doesn't get sent to the database.
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from company in companies.ToList()
select new
{
i = company.Id,
cell = new string[] { company.Id.ToString(), ""+company.Name.ToString()+"" }
}).ToArray()
};
It's trying to translate the i to SQL and failing. The query that gets generated is something close to
SELECT companies.Id,
'' + companies.Name + ''
FROM companies
Basically, your string concatenation is being sent to your SQL server.

Resources