Join list into string - c#

I need to join List of string into string inside linq select.
I tried that:
var myEnt = from p in ctx.Project
select new ProjectRepository.Project
{
Id = p.ProjectId,
Desc = p.ProjectDesc,
UsersProject = String.Join("; ", (
from up in ctx.usersProject join u in ctx.users
on up.user equals u.id into uloj from uj in uloj.DefaultIfEmpty()
where (up.deleted ?? false) == false
&& up.projectId == p.Id
&& (uj.deleted ?? false) == false
select uj.name + " " + uj.surname).ToList())
});
gridProg.DataSource = myEnt.ToList();
gridProg.DataBind();
But i had this error:
Data binding directly to a store query (DbSet, DbQuery, DbSqlQuery, DbRawSqlQuery) is not supported. Instead populate a DbSet with data, for example by calling Load on the DbSet, and then bind to local data. For WPF bind to DbSet.Local. For WinForms bind to DbSet.Local.ToBindingList(). For ASP.NET WebForms you can bind to the result of calling ToList() on the query or use Model Binding, for more information see http://go.microsoft.com/fwlink/?LinkId=389592.
Thank you.
UPDATE
New error after adding .Tolist() to DataSource binding.
LINQ to Entities does not recognize the method 'System.String Join(System.String, System.Collections.Generic.IEnumerable`1[System.String])' method, and this method cannot be translated into a store expression.

I have not tested it, but it will work. Make 2 different Queries
var Projects = (from up in ctx.usersProject join u in ctx.users
on up.user equals u.id into uloj from uj in uloj.DefaultIfEmpty()
where (up.deleted ?? false) == false
&& up.projectId == p.Id
&& (uj.deleted ?? false) == false
select new {
ProjectId = up.projectId,
ProjectsList = uj.name + " " + uj.surname
}).ToList();
var myEnt = from p in ctx.Project.AsEnumerable()
select new ProjectRepository.Project
{
Id = p.ProjectId,
Desc = p.ProjectDesc,
UsersProject = String.Join("; ", Projects.Where(e=> p.ProjectId == e.ProjectId).Select(e=> e.ProjectsList).ToList())
}).ToList();

I found the solution. I post the code below:
var usersProject = (from up in ctx.usersProject join u in ctx.users
on up.user equals u.id into uloj from uj in uloj.DefaultIfEmpty()
where (up.deleted ?? false) == false
&& up.projectId == p.Id
&& (uj.deleted ?? false) == false
select new {
ProjectId = up.projectId,
User = uj.name + " " + uj.surname
}).ToList();
var myEnt = from p in ctx.Project.AsEnumerable()
select new ProjectRepository.Project
{
Id = p.ProjectId,
Desc = p.ProjectDesc
}).ToList();
var myEntL = myEnt.ToList();
foreach (var mysingleEnt in myEntL)
{
myEntL.Where(x => x.Id == mysingleEnt.Id).FirstOrDefault().utentiAssociati =
String.Join("; ", usersProject
.Where(x => x.ProjectId == mysingleEnt.Id).Select(x => x.User).ToList());
}
gridProg.DataSource = myEntL;
gridProg.DataBind();
Thank you for help.

Related

Convert list of string into a comma separated string using lambda expression query

I am attaching my full query in which ps.productId is returning list of strings and I want all strings comma separated as a single string like "a,b,c"
How can I achieve this using lambda expression!
ProductIDs = string.Join(",", ps.ProductID),
ProductIDs = string.Join(",", _DataContext.ProductSelectionEntity.Where(x => x.BillingId == bill.Id).Select(x => x.ProductID).ToList())
ps.productIds will return a List<string>, I want it in a string format "1,2,3,4"
var results = (from uastatus in _DataContext.UaStatusEntity
where uastatus.IsUaComplete == false
join client in _DataContext.Client on uastatus.ClientID equals client.ClientID
where client.ClientStatus == "Active" &&
client.IsEnrolledNHCR.HasValue &&
client.IsEnrolledNHCR.Value
join ps in _DataContext.ProductSelectionEntity on bill.ClientId equals ps.ClientID
where bill.Id == ps.BillingId
select new PendingUA
{
ClientId = client.ClientID,
ClientRelationship = client.ClientRelationship,
ClientName = client.ClientName,
EIN = client.EIN,
ProductIDs = string.Join(",", ps.ProductID),
ProductIDs = string.Join(",",_DataContext.ProductSelectionEntity.Where(x => x.BillingId == bill.Id).Select(x => x.ProductID).ToList())
}).Distinct().ToList();
Error message
You must extract value from database before use string.Join
var resultsFromDB = (from uastatus in _DataContext.UaStatusEntity
where uastatus.IsUaComplete == false
join client in _DataContext.Client on uastatus.ClientID equals client.ClientID
where client.ClientStatus == "Active" &&
client.IsEnrolledNHCR.HasValue &&
client.IsEnrolledNHCR.Value
join ps in _DataContext.ProductSelectionEntity on bill.ClientId equals ps.ClientID
where bill.Id == ps.BillingId
select new
{
ClientId = client.ClientID,
ClientRelationship = client.ClientRelationship,
ClientName = client.ClientName,
EIN = client.EIN,
ProductID = ps.ProductID,
}).ToList();
var results = (from value in resultsFromDB
let ProductIDS = string.Join(",", resultsFromDB.Where(x => x.ClientId == value.ClientId ).Select(x => x.ProductID).ToList())
select new PendingUA
{
ClientId = value.ClientID,
ClientRelationship = value.ClientRelationship,
ClientName = value.ClientName,
EIN = value.EIN,
ProductIDS = ps.ProductIDS ,
}).Distinct().ToList();
for better performance, use linq group by

Converted sql query to linq but not getting any result

As I am new to Linq and Entity Framework.
The following is my working stored procedure which includes a value that is a comma separated string (the SUBSTRING clause)
SELECT DISTINCT
SR.StudentRequestId,
SR.RegistrationId,
SR.Location,
SR.PaymentMethod,
SR.CreatedOn,
C.ClassName,
CC.CampusName,
CASE WHEN ISNULL(TSR.StatusId,0)=0 THEN 1 ELSE TSR.StatusId END AS StatusId,
SUBSTRING(
(SELECT', ' + REPLACE(REPLACE(ST1.FromTime,'AM',''),'PM','') + '-'+ ST1.ToTime AS [text()]
FROM dbo.StudentRequestTimings ST1
WHERE ST1.StudentRequestId = SRT.StudentRequestId
ORDER BY ST1.CreatedOn FOR XML PATH ('')
), 2, 1000) [Time] FROM StudentRequest SR
INNER JOIN Registration R ON R.RegistrationId = SR.RegistrationId
INNER JOIN Campus CC ON CC.CampusId = R.CampusId
INNER JOIN Class C ON C.ClassId = SR.ClassId
LEFT JOIN TutorClasses TC ON SR.ClassId = TC.ClassId
LEFT JOIN StudentRequestTimings SRT ON SR.StudentRequestId = SRT.StudentRequestId
LEFT JOIN TutorStudentRequest TSR ON TSR.StudentRequestId = SRT.StudentRequestId AND TutorId = #RegistrationId
WHERE TC.RegistrationId = #RegistrationId
ORDER BY SR.CreatedOn DESC
I have a requirement to use this data in a PagedList method that accepts a IQueryable<T> and I want to convert this SP to a LINQ query that returns a IQueryable (internally the PagedList method uses .Skip() and .Take() to perform server side paging).
The following is my attempt so far, but I do not know why i am not getting to get the expected result as getting from SQL query. I think some thing is wrong in my below code. Can any one identify what is wrong in below code?
var model = (from sr in db.StudentRequests
join r in db.Registrations on sr.RegistrationId equals r.RegistrationId
join cc in db.Campus on r.CampusId equals cc.CampusId
join c in db.Classes on sr.ClassId equals c.ClassId
from tc in db.TutorClasses.Where(t => t.ClassId == sr.ClassId).DefaultIfEmpty()
from srt in db.StudentRequestTimings.Where(s => s.StudentRequestId == sr.StudentRequestId).DefaultIfEmpty()
from tsr in db.TutorStudentRequests.Where(t => t.StudentRequestId == srt.StudentRequestId && t.TutorId == registrationid).DefaultIfEmpty()
where tc.RegistrationId == registrationid
select new TutorDashboard
{
StudentRequestId = sr.StudentRequestId,
RegistrationId = sr.RegistrationId,
Location = sr.Location,
PaymentMethod = sr.PaymentMethod,
CreatedOn = sr.CreatedOn,
ClassName = c.ClassName,
CampusName = cc.CampusName,
Time = string.Join(",", db.StudentRequestTimings.Where(p => p.StudentRequestId == sr.StudentRequestId).Select(p => p.FromTime.ToString().Replace("AM", "").Replace("PM", "") + "-" + p.ToTime.ToString())),
}).Distinct();
Can any one help me out for why I am not getting proper result from above linq query?
Issue is that on adding below code to Linq I am facing issue, How can I resolve this
Time = string.Join(",", db.StudentRequestTimings.Where(p => p.StudentRequestId == sr.StudentRequestId).Select(p => p.FromTime.ToString().Replace("AM", "").Replace("PM", "") + "-" + p.ToTime.ToString())),
I had added this code because I want to get a single string from multiple row
1:00-1:30 PM, 2:00=2:30 PM
5:00-5:30 PM
Like wise
As there was an issue in converting comma seperated code I had implement below code
var query = (from sr in db.StudentRequests
join r in db.Registrations on sr.RegistrationId equals r.RegistrationId
join cc in db.Campus on r.CampusId equals cc.CampusId
join c in db.Classes on sr.ClassId equals c.ClassId
from tc in db.TutorClasses.Where(t => t.ClassId == sr.ClassId).DefaultIfEmpty()
from srt in db.StudentRequestTimings.Where(s => s.StudentRequestId == sr.StudentRequestId).DefaultIfEmpty()
from tsr in db.TutorStudentRequests.Where(t => t.StudentRequestId == srt.StudentRequestId && t.TutorId == registrationid).DefaultIfEmpty()
where tc.RegistrationId == registrationid
select new
{
StudentRequestId = sr.StudentRequestId,
RegistrationId = sr.RegistrationId,
Location = sr.Location,
PaymentMethod = sr.PaymentMethod,
CreatedOn = sr.CreatedOn,
ClassName = c.ClassName,
CampusName = cc.CampusName,
StatusId = tsr.StatusId == null ? 1 : tsr.StatusId,
Time = db.StudentRequestTimings.Where(p => p.StudentRequestId == sr.StudentRequestId).Select(p => p.FromTime.ToString().Replace("AM", "").Replace("PM", "") + "-" + p.ToTime)
}).ToList().GroupBy(p => new { p.StudentRequestId }).Select(g => g.First()).ToList();
var model = query.AsEnumerable().Select(x => new TutorDashboard
{
StudentRequestId = x.StudentRequestId,
RegistrationId = x.RegistrationId,
Location = x.Location,
PaymentMethod = x.PaymentMethod,
CreatedOn = x.CreatedOn,
ClassName = x.ClassName,
CampusName = x.CampusName,
StatusId = x.StatusId == null ? 1 : x.StatusId,
Time = string.Join(",", x.Time),
}).ToList().ToPagedList(page ?? 1, 1);
May this code will be helpful to some who need comma separated value with multiple left join

how to do search of a group of words in a nested linq query fields

//I tried to implement global search using the below query
//my linq query :
var query = (from ug in db.SC_UserGroup
where ug.IsDeleted == false && ug.TenantID == tenantId && ug.ParentGroup == defaultGuid && ug.GroupTypeID == manualCodeTypeId
select new
{
GroupID = ug.ID,
GroupTypeID = ug.GroupTypeID,
GroupName = ug.GroupName,
Description = ug.Description,
TenantId = ug.TenantID,
SubGroups = (from sug in db.SC_UserGroup
where sug.ParentGroup == ug.ID && sug.IsDeleted == false && sug.TenantID == tenantId
select new
{
GroupID = sug.ID,
GroupTypeID = sug.GroupTypeID,
GroupName = sug.GroupName,
Description = sug.Description,
TenantId = sug.TenantID,
users = (from sugm in db.SC_UserGroupMap
join su in db.SC_User on sugm.UserID equals su.ID
join usertenantmap in db.SC_UserTenantMap on su.ID equals usertenantmap.UserID
join userCredential in db.SC_UserCredential on usertenantmap.UserCredentialID equals userCredential.ID
where su.IsDeleted.Value == false && sugm.UserGroupID == sug.ID && sugm.IsDeleted == false
select new
{
UserId = su.ID,
UserName = (su.FirstName + " " + su.LastName),
EmailId = userCredential.Email
}).Distinct().ToList()
})
});
// here my search array contails the list of words to search
if (searchArray[0] != string.Empty)
{
//like this i am able to search on GroupName and Description column
query = query.Where(x => searchArray.All(y => x.GroupName.Contains(y) || x.Description.Contains(y)));
}
MY question :
I want to search on fields of sub- query fields (i.e on SubGroups fields in the current context)
If you want to do the same search on fields in SubGroups you'll have to use All or Any depending on if you want all the items in SubGroups to match or at least one.
query = query.Where(
x => searchArray.All(
y => x.GroupName.Contains(y) ||
x.Description.Contains(y) ||
x.SubGroups.Any(sg => sg.GroupName.Contains(y) ||
x.SubGroups.Any(sg => sg.Description.Contains(y))));

Linq to select data from one table not in other table

Hi i have the following code to select data from one table not in other table
var result1 = (from e in db.Users
select e).ToList();
var result2 = (from e in db.Fi
select e).ToList();
List<string> listString = (from e in result1
where !(from m in result2
select m.UserID).Contains(e.UserID)
select e.UserName).ToList();
ViewBag.ddlUserId = listString;
Am getting value inside listString .But got error while adding listString to viewbag.
Unable to cast object of type 'System.Collections.Generic.List`1[System.String]' to type 'System.Collections.Generic.IEnumerable`1[Main.Models.Admin.User]'.
First, could you update your question with the entire method so that we can see what might be going on with the ViewBag? Because your code should work just fine, assigning whatever value to the ViewBag is no problem normally:
ViewBag.property1 = 0;
ViewBag.property1 = "zero";
works just fine. ViewBag is dynamic. Now, you could get that error if you would later try to assing ViewBag.ddlUserId to something that actually is the wrong type.
I would like you to rewrite your statement as well, let me explain why. Assume for a moment that you have a lot ( > 100.000) of User records in your db.Users and we assume the same for Fi as well. In your code, result1 and result2 are now two lists, one containing >100.000 User objects and the other >100.000 Fi objects. Then these two lists are compared to each other to produce a list of strings. Now imagine the resource required for your web server to process this. Under the assumption that your actually using/accessing a separate SQL server to retrieve your data from, it would be a lot better and faster to let that server do the work, i.e. producing the list of UserID's.
For that you'd either use Kirill Bestemyanov's answer or the following:
var list = (from user in db.Users
where !db.Fi.Any(f => f.UserID == user.UserID)
select user.UserName).ToList()
This will produce just one query for the SQL server to execute:
SELECT
[Extent1].[UserName] AS [UserName]
FROM [dbo].[Users] AS [Extent1]
WHERE NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Fi] AS [Extent2]
WHERE [Extent2].[UserID] = [Extent1].[UserID]
)}
which in the end is what you want...
Just to clarify more:
var list = (from user in db.Users
where !db.Fi.Any(f => f.UserID == user.UserID)
select user.UserName).ToList()
can be written as the following lambda expression as well:
var list = db.Users.Where(user => !db.Fi.Any(f => f.UserID == user.UserID))
.Select(user => user.UserName).ToList()
which from the looks of it is slightly different from Kirill Bestemyanov's answer (which I slightly modified, just to make it look more similar):
var list = db.Users.Where(user => !db.Fi.Select(f => f.UserID)
.Contains(user.UserID))
.Select(user => user.UserName).ToList();
But, they will in fact produce the same SQL Statement, thus the same list.
I will rewrite it to linq extension methods:
List<string> listString = db.Users.Where(e=>!db.Fi.Select(m=>m.UserID)
.Contains(e.UserID))
.Select(e=>e.UserName).ToList();
try it, it should work.
Try this it is very simple.
var result=(from e in db.Users
select e.UserID).Except(from m in db.Fi
select m.UserID).ToList();
var res = db.tbl_Ware.where(a => a.tbl_Buy.Where(c => c.tbl_Ware.Title.Contains(mtrTxtWareTitle.Text)).Select(b => b.Ware_ID).Contains(a.ID));
This mean in T-SQL is:
SELECT * FROM tbl_Ware WHERE id IN (SELECT ware_ID, tbl_Buy WHErE tbl_Ware.title LIKE '% mtrTxtwareTitle.Text %')
getdata = (from obj in db.TblManageBranches
join objcountr in db.TblManageCountries on obj.Country equals objcountr.iCountryId.ToString() into objcount
from objcountry in objcount.DefaultIfEmpty()
where obj.IsActive == true
select new BranchDetails
{
iBranchId = obj.iBranchId,
vBranchName = obj.vBranchName,
Addressline1 = obj.Addressline1,
Adminemailid = obj.Adminemailid,
BranchType = obj.BranchType,
Country = objcountry.vCountryName,
CreatedBy = obj.CreatedBy,
CreatedDate = obj.CreatedDate,
iArea = obj.iArea,
iCity = obj.iCity,
Infoemailid = obj.Infoemailid,
Landlineno = obj.Landlineno,
Mobileno = obj.Mobileno,
iState = obj.iState,
Pincode = obj.Pincode,
Processemailid = obj.Processemailid,
objbranchbankdetails = (from objb in db.TblBranchesBankDetails.Where(x => x.IsActive == true && x.iBranchId == obj.iBranchId)
select new ManageBranchBankDetails
{
iBranchId = objb.iBranchId,
iAccountName = objb.iAccountName,
iAccountNo = objb.iAccountNo,
iBankName = objb.iBankName,
iAccountType = objb.iAccountType,
IFSCCode = objb.IFSCCode,
SWIFTCode = objb.SWIFTCode,
CreatedDate = objb.CreatedDate,
Id = objb.Id
}).FirstOrDefault(),
objbranchcontactperson = (from objc in db.tblbranchcontactpersons.Where(x => x.Isactive == true && x.branchid == obj.iBranchId)
select new ManageBranchContactPerson
{
branchid = objc.branchid,
createdate = objc.createdate,
Id = objc.Id,
iemailid = objc.iemailid,
ifirstname = objc.ifirstname,
ilandlineno = objc.ilandlineno,
ilastname = objc.ilastname,
imobileno = objc.imobileno,
title = objc.title,
updateddate=objc.updateddate,
}).ToList(),
}).OrderByDescending(x => x.iBranchId).ToList();
getdata = (from obj in db.TblManageBranches join objcountr in db.TblManageCountries on obj.Country equals objcountr.iCountryId.ToString() into objcount from objcountry in objcount.DefaultIfEmpty() where obj.IsActive == true
select new BranchDetails
{
iBranchId = obj.iBranchId,
vBranchName = obj.vBranchName,
objbranchbankdetails = (from objb in db.TblBranchesBankDetails.Where(x => x.IsActive == true && x.iBranchId == obj.iBranchId)
select new ManageBranchBankDetails
{
iBranchId = objb.iBranchId,
iAccountName = objb.iAccountName,
}).FirstOrDefault(),
objbranchcontactperson = (from objc in db.tblbranchcontactpersons.Where(x => x.Isactive == true && x.branchid == obj.iBranchId)
select new ManageBranchContactPerson
{
branchid = objc.branchid,
createdate = objc.createdate,
Id = objc.Id,
iemailid = objc.iemailid,
}).ToList(),
}).OrderByDescending(x => x.iBranchId).ToList();

Call Method from Linq query

I am using Linq query and call method Like..
oPwd = objDecryptor.DecryptIt((c.Password.ToString())
it will return null value.
Means this will not working.
how I Resolve this.
Thanks..
var q =
from s in db.User
join c in db.EmailAccount on s.UserId equals c.UserId
join d in db.POPSettings
on c.PopSettingId equals d.POPSettingsId
where s.UserId == UserId && c.EmailId == EmailId
select new
{
oUserId = s.UserId,
oUserName = s.Name,
oEmailId = c.EmailId,
oEmailAccId = c.EmailAccId,
oPwd = objDecryptor.DecryptIt(c.Password.ToString()),
oServerName = d.ServerName,
oServerAdd = d.ServerAddress,
oPOPSettingId = d.POPSettingsId,
};
If that is LINQ-to-SQL or Entity Framework. You'll need to break it into steps (as it can't execute that at the DB). For example:
var q = from s in db.User
join c in db.EmailAccount on s.UserId equals c.UserId
join d in db.POPSettings on c.PopSettingId equals d.POPSettingsId
where s.UserId == UserId && c.EmailId == EmailId
select new
{
oUserId = s.UserId,
oUserName = s.Name,
oEmailId = c.EmailId,
oEmailAccId = c.EmailAccId,
oPwd = c.Password,
oServerName = d.ServerName,
oServerAdd = d.ServerAddress,
oPOPSettingId = d.POPSettingsId,
};
then use AsEnumerable() to break "composition" against the back-end store:
var query2 = from row in q.AsEnumerable()
select new
{
row.oUserId,
row.oUserName,
row.oEmailId,
row.oEmailAccId,
oPwd = objDecryptor.DecryptIt(row.oPwd),
row.oServerName,
row.oServerAdd,
row.oPOPSettingId
};
var q = from s in db.User
join c in db.EmailAccount on s.UserId equals c.UserId
join d in db.POPSettings on c.PopSettingId equals d.POPSettingsId
where s.UserId == UserId && c.EmailId == EmailId
select new
{
oUserId = s.UserId,
oUserName = s.Name,
oEmailId = c.EmailId,
oEmailAccId = c.EmailAccId,
oPwd = c.Password,
oServerName = d.ServerName,
oServerAdd = d.ServerAddress,
oPOPSettingId = d.POPSettingsId,
};
foreach (var item in q)
{
item.oPwd = objDecryptor.DecryptIt(row.oPwd),
}
we can use a foreach loop also to update a single property. do not need to select all property in next query.
This has nothing about Linq query. you need to debug method objDecryptor.DecryptIt

Categories