Concat strings in a projection (Linq) - c#

How can I concat two string in a projection?
This is what I have so far:
IEnumerable<NameIdentity> data = null;
JsonResult res;
using (DBContext _db = new DBContext())
{
data = MyEntity.GetEntities(_db).OrderBy(a=> a.name)
.Select(b=> new NameIdentity
{
ID = b.entityID,
Name = String.Join(" - ", new String[]{ b.year, b.name })
});
res = Json(data.ToList(), JsonRequestBehavior.AllowGet);
}
I need to concatenate the year and name properties in the Name propety of my projection.
The error that is giving me is an "NotSupportedException" that says that the LINQ to Entities doesn't recognize de Join() method and it cannot be translated to a store expression.

data = MyEntity.GetEntities(_db).OrderBy(a=> a.name)
.Select(b=> new NameIdentity
{
ID = b.entityID,
Name = b.year +"-" + b.name
});

While you are using linq-to-entities you cannot use arbitrary .NET methods in query, You can use EdmFunctions, Here I have use EdmFunctions.Concat
data = MyEntity.GetEntities(_db).OrderBy(a=> a.name)
.Select(b=> new NameIdentity
{
ID = b.entityID,
Name = EdmFunctions.Concat(b.year, "-", b.name)
});
You can also use Canonical functions

Related

How to change in elegant way List<> structure

I am using LINQ to entitiy in my project.
I have this LINQ:
var result = (from inspArch in inspectionArchives
from inspAuth in inspArch.InspectionAuthority
select new
{
Id = inspArch.Id,
clientId = inspArch.CustomerId,
authId = inspAuth.Id
}).ToList();
After LINQ is executed result has this value :
Is there any elegant way (for example using LINQ or change above existing LINQ) to create from the list above, new list like that:
I haven't built this to see if it compiles, but this should work. You need to aggregate the Id and AuthId fields.
var result = (from inspArch in inspectionArchives
from inspAuth in inspArch.InspectionAuthority
select new
{
Id = inspArch.Id,
clientId = inspArch.CustomerId,
authId = inspAuth.Id
})
.GroupBy(g => g.clientId)
.select(s => new {
Id = string.Join(",", s.Select(ss => ss.Id.ToString())),
ClientId = s.Key,
AuthId = string.Join(",", s.Select(ss => ss.authId.ToString()).Distinct()),
}).ToList();
You need group by and you can apply String.Join on the resulting IGrouping:-
var result = (from inspArch in inspectionArchives
from inspAuth in inspArch.InspectionAuthority
group new { inspArch, inspAuth } by inspArch.CustomerId into g
select new
{
Id = String.Join(",",g.Select(x => x.inspArch.Id),
clientId = x.Key,
authId = String.Join(",",g.Select(x => x.inspAuth.Id)
}).ToList();
The tricky part here is to group both objects i.e. new { inspArch, inspAuth } because we need to access properties from both.
Update:
Since this is entity framework, it won't be able to translate the method String.Join to SQL, so we can bring back the grouped object to memory using AsEnumerable and then project it like this:-
var result = (from inspArch in inspectionArchives
from inspAuth in inspArch.InspectionAuthority
group new { inspArch, inspAuth } by inspArch.CustomerId into g
select g).AsEnumerable()
.Select(g => new
{
Id = String.Join(",",g.Select(x => x.inspArch.Id),
clientId = x.Key,
authId = String.Join(",",g.Select(x => x.inspAuth.Id)
}).ToList();

Combine two list data into single list C#

So i have following two list using linq.
List<One> one= A.Common
.Join(B.Common,
a => a.ID,
b=> b.ID,
(a, b) => new One
{
ID = b.PID,
Name = b.PCName,
LastName = a.LName
}).ToList();
List<One> two = (from c in D.Options
select new One
{
MainName = c.mName
}).ToList();
List<One> sn = one.Concat(two).ToList();
I am concating both list. But when i debug i am getting MainName as null in sn list.
How do i get data from both list in single list??
This is how you do it:
var sn = one.Zip(two, (x, y) => new One{
ID = x.ID,
Name = x.Name,
LastName = x.LastName,
MainName = y.MainName
});
You want the MainName property assigned for all the list values in List ONE ?
As from above code concatenation will join two list and the MainName will be not set for list one elements.
one.Concat(two)
Above line will just concat the both lists to one list elements.
You can use the LINQ Concat and ToList methods:
var mergedList = YourFirstList.Concat(YourSecondList)
.Concat(YourThirdList)
.ToList();
Edit:
one.Concat(two).Select(g => g.Aggregate((p1,p2) => new One
{
ID = p1.ID,
Name = p1.PCName,
LastName = p1.LName,
MainName = p2.mName
}));
more efficient ways to do this - the above will basically loop through all the entries, creating a dynamically sized buffer.
var mergedList = new List<One>(YourFirstList.Count +
YourSecondList.Count +
YourThirdList.Count);
mergedList.AddRange(YourFirstList);
mergedList.AddRange(YourSecondList);
mergedList.AddRange(YourThirdList);
AddRange is special-cased for ICollection<T> for efficiency.
You can use the Zip method.
one.Zip(two,(o1, o2) => new One()
{
ID = o1.ID,
Name = o1.PCName,
LastName = o1.LName,
MainName = o2.mName
});

linq to entities throwing some error

hi i am using this controller
public ActionResult gridview()
{
var jsonData = new {
total = 1, //todo: calculate
page = 1,
records = db.TestModels.Count(),
rows = (
from question in db.TestModels
select new {
id = question.Dataid,
cell = new string[] {
question.Dataid, question.Name, question.Emailid
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
}
am getting this error
LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.
can any body help
You are trying to use new string[] in a SQL query, but that cannot be translated to SQL. You need to get the data you need from the model, and perform the conversion in-memory. Use .AsEnumerable() to indicate you want to do the following in-memory, and not in the SQL statement.
Something like this:
var jsonData = new {
total = 1, //todo: calculate
page = 1,
records = db.TestModels.Count(),
rows = db.TestModels
.Select(x => new { x.Dataid, x.Name, x.Emailid })
.AsEnumerable()
.Select(x => new {
id = x.DataId,
cell = new string[3] { x.Dataid, x.Name, x.Emailid }
})
.ToArray();
};

Get a comma separated list of entity collection using linq

I have 2 entities Line and Tag. The relation is Line *----* Tag
From line I have a navigation property Line.Tags which returns a list of Tag objects. The Tag.Name is the string value im after.
What I really need is to get all the tag names in a comma seperated way like so :
tag1, tag2, tag3
I tried to do this in a projection, but it said it doesnt support toString()
var o = dgvLines.CurrentRow.DataBoundItem as Order;
var r = _rs.Lines.Where(y => y.InvoiceNo == o.InvoiceNo).Select(x => new
{
ReturnNo = x.Return.ReturnNo,
Part = x.Part,
Tags = String.Join(", ", x.Tags.ToList().Select(t => t.Name))
});
dgvExistingParts.DataSource = r;
Error:
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.
Any idea how I can get this comma separated list of tags?
Thanks in advance.
var r = _rs.Lines.Where(y => y.InvoiceNo == o.InvoiceNo).ToList().Select(x => new
{
ReturnNo = x.Return.ReturnNo,
Part = x.Part,
Tags = String.Join(", ", x.Tags.Select(t => t.Name))
});
You can't do the concatenation in SQL, so you have to get back the data you need and then work in normal code:
var o = dgvLines.CurrentRow.DataBoundItem as Order;
var r = _rs.Lines
.Where(y => y.InvoiceNo == o.InvoiceNo)
.Select(x => new
{
ReturnNo = x.Return.ReturnNo,
Part = x.Part,
TagNames = x.Tags.Select( t => t.Name ),
}
)
.ToList() // this runs the SQL on the database
.Select( x => new
{
ReturnNo = x.ReturnNo,
Part = x.Part,
Tags = String.Join( ", ", x.TagNames ),
}
)
.ToList();
dgvExistingParts.DataSource = r;

How do you do alias in Select method (LINQ)

I'm trying to alias the string list with a named column:
var providers = EMRRepository.GetProviders().Select(x => x as name);
where 'GetProviders()' returns a List<string>
It's called a "Projection", just select a new anonymous type.
var projection = data.Select( x => new { FieldName = x.Property } );
You are looking to select into a new anonymous type.
var providers = EMRRepository.GetProviders().Select(x => new { Name = x });

Categories

Resources