Can i convert from byte[] to String in Lambda? - c#

Additional information: LINQ to Entities does not recognize the method 'System.String ToString(System.Object)' method, and this method cannot be translated into a store expression.
Ok, "ToString()" cannot be translated into a store expression, and error is clear.
This is my code:
var narudzbe = db.Narudzbe
.Where(x => x.KupacID == id && x.Status == true)
.Select(x => new NarudzbeVM()
{
BrojNarudzbe = x.BrojNarudzbe,
Datum = x.Datum,
KupacID = x.KupacID,
NarudzbaID = x.NarudzbaID,
Otkazano = x.Otkazano,
Status = x.Status,
StavkeNarudzbe = db.NarudzbaStavke
.Where(y => y.NarudzbaID == x.NarudzbaID)
.Select(z => new NarudzbaStavkeVM()
{
Kolicina = z.Kolicina,
NarudzbaID = z.NarudzbaID,
NarudzbaStavkaID = z.NarudzbaStavkaID,
Proizvod = db.Proizvodi
.Select(t => new ProizvodTest()
{
Cijena = t.Cijena,
ProizvodID = t.ProizvodID,
JedinicaMjere = t.JediniceMjere.Naziv,
Naziv = t.Naziv,
Sifra = t.Sifra,
SlikaThumb = Convert.ToString(t.SlikaThumb)
})
.Where(k => k.ProizvodID == z.ProizvodID)
.FirstOrDefault()
}).ToList()
}).ToList();
I want to convert byte[] to string, since my class accept string for attribut "SlikaThumb". So,
SlikaThumb = Convert.ToString(t.SlikaThumb)
t.SlikaThumb is type of byte[]. Is there way to do it in lambda ?

As you've said, Linq to Entities doesn't recognize .ToString() calls; it doesn't know how to convert these into SQL. However, you can run that in memory; simply resolve the objects (call .ToList() or something) and then perform the select statement on the in-memory objects. It'll be Linq to Objects and that'll be permitted.
Whether that will work for the purpose you intend is a different question but you definitely will be able to call .ToString() on any object in this way.

I guess the best thing you could do is retrieve the object from database as they are, by using ToList() or an equivalent method to actually do the query, then after that, you work on the retrieved list to convert to the objects you want to send to Android. As far as I know, there is no translated method to T-SQL from LinqToEntities to convert a binary field into a Base64 string.

Ok, this helps. As #Casey say:
Linq to Entities doesn't recognize .ToString() calls; it doesn't know how to convert these into SQL. However, you can run that in memory; simply resolve the objects (call .ToList() or something) and then perform the select statement on the in-memory objects. It'll be Linq to Objects and that'll be permitted.
I tried it on my code and it works. What i done ? I first call ToList() method whenever i getting data from database, and then perform the operations.
This code works fine...
List<NarudzbeVM> narudzbe = db.Narudzbe.Where(x => x.KupacID == id).ToList().
Select(x => new NarudzbeVM()
{
BrojNarudzbe = x.BrojNarudzbe,
Datum = x.Datum,
KupacID = x.KupacID,
NarudzbaID = x.NarudzbaID,
Otkazano = x.Otkazano,
Status = x.Status,
StavkeNarudzbe = db.NarudzbaStavke.Where(y => y.NarudzbaID == x.NarudzbaID).ToList().
Select(z => new NarudzbaStavkeVM()
{
Kolicina = z.Kolicina,
NarudzbaID = z.NarudzbaID,
NarudzbaStavkaID = z.NarudzbaStavkaID,
ProizvodID = z.ProizvodID,
Proizvod = db.Proizvodi.Where(k => k.ProizvodID == z.ProizvodID).ToList().
Select(t => new ProizvodTest()
{
Cijena = t.Cijena,
ProizvodID = t.ProizvodID,
JedinicaMjere = t.JediniceMjere.Naziv,
VrstaProizvoda = t.VrsteProizvoda.Naziv,
Naziv = t.Naziv,
Sifra = t.Sifra,
SlikaThumb = Convert.ToBase64String(t.SlikaThumb),
}).FirstOrDefault()
}).ToList()
}).ToList();

try with this
string yourString= System.Text.Encoding.Default.GetString(
System.Text.Encoding.Default.GetBytes(yorbyteArray));

Related

Factoring Linq Where clause for different EF objets [duplicate]

I'm getting the following error when trying to do a linq query:
LINQ to Entities does not recognize the method 'Boolean
IsCharityMatching(System.String, System.String)' method, and this
method cannot be translated into a store expression.
I've read lots of previous questions where people get the same error, and if I understand this correctly it's because LINQ to Entities requires the whole linq query expression to be translated to a server query, and therefore you can't call an outside method in it. I haven't been able to convert my scenario into something that works yet, and my brain is starting to melt down, so I was hoping someone could point me in the right direction. We're using Entity Framework and the specification pattern (and I'm new to both).
Here's the code that uses the specification:
ISpecification<Charity> specification = new CharitySearchSpecification(charityTitle, charityReference);
charities = charitiesRepository.Find(specification).OrderBy(p => p.RegisteredName).ToList();
Here's the linq expression:
public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
return p => p.IsCharityMatching(this.charityName, this.charityReference);
}
Here's the IsCharityMatching method:
public bool IsCharityMatching(string name, string referenceNumber)
{
bool exists = true;
if (!String.IsNullOrEmpty(name))
{
if (!this.registeredName.ToLower().Contains(name.ToLower()) &&
!this.alias.ToLower().Contains(name.ToLower()) &&
!this.charityId.ToLower().Contains(name.ToLower()))
{
exists = false;
}
}
if (!String.IsNullOrEmpty(referenceNumber))
{
if (!this.charityReference.ToLower().Contains(referenceNumber.ToLower()))
{
exists = false;
}
}
return exists;
}
Let me know if you need any more information.
Many thanks,
Annelie
As you've figured out, Entity Framework can't actually run your C# code as part of its query. It has to be able to convert the query to an actual SQL statement. In order for that to work, you will have to restructure your query expression into an expression that Entity Framework can handle.
public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
string name = this.charityName;
string referenceNumber = this.referenceNumber;
return p =>
(string.IsNullOrEmpty(name) ||
p.registeredName.ToLower().Contains(name.ToLower()) ||
p.alias.ToLower().Contains(name.ToLower()) ||
p.charityId.ToLower().Contains(name.ToLower())) &&
(string.IsNullOrEmpty(referenceNumber) ||
p.charityReference.ToLower().Contains(referenceNumber.ToLower()));
}
I got the same error in this code:
var articulos_en_almacen = xx.IV00102.Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();
this was the exactly error:
System.NotSupportedException: 'LINQ to Entities does not recognize the method 'Boolean Exists(System.Predicate`1[conector_gp.Models.almacenes_por_sucursal])' method, and this method cannot be translated into a store expression.'
I solved this way:
var articulos_en_almacen = xx.IV00102.ToList().Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();
I added a .ToList() before my table, this decouple the Entity and linq code, and avoid my next linq expression be translated
NOTE: this solution isn't optimal, because avoid entity filtering, and simply loads all table into memory
I ran into the same problem today, this was the first link I hit. However I was not looking for verifying my query. So if somebody else has the same issue and are looking for this solution it is added here. My issue was in another link.
It is the most common exception occurs when working with entity framework and converting data inside IQueryable result for filtering.
using (var context = new CustomerContext())
{
var item = context.InvoiceItems
.Where(i => i.Code == code.ToString())
.FirstOrDefault();
}
Several solutions exist. Move ToString() call to a separate line.
using (var context = new CustomerContext())
{
string codeStr = code.ToString();
var item = context.InvoiceItems
.Where(i => i.Code == codeStr)
.FirstOrDefault();
}
Use EF Extension Method,
using (var context = new CustomerContext())
{
var item = context.InvoiceItems
.Where(i => i.Code == SqlFunctions.StringConvert(code))
.FirstOrDefault();
}
Convert IQueryable result to IEnumerable before Filtering
using (var context = new CustomerContext())
{
var item = context.InvoiceItems.AsEnumerable()
.Where(i => i.Code == code.ToString())
.FirstOrDefault();
}
If anyone is looking for a VB.Net answer (as I was initially), here it is:
Public Function IsSatisfied() As Expression(Of Func(Of Charity, String, String, Boolean))
Return Function(charity, name, referenceNumber) (String.IsNullOrWhiteSpace(name) Or
charity.registeredName.ToLower().Contains(name.ToLower()) Or
charity.alias.ToLower().Contains(name.ToLower()) Or
charity.charityId.ToLower().Contains(name.ToLower())) And
(String.IsNullOrEmpty(referenceNumber) Or
charity.charityReference.ToLower().Contains(referenceNumber.ToLower()))
End Function
I got the same error in this code:
Solution
IQueryable to .toList() is the best option

Converting linq select into model, LINQ to Entities does not recognize the method, and this method cannot be translated into a store expression

Hi I i'm doing this linq expression in an web api but then it gives this error
LINQ to Entities does not recognize the method 'WebApplicationAPI.Models.Registo convertToRegisto(WebApplicationAPI.Models.TBS0017)' method, and this method cannot be translated into a store expression.
Here's the code:
var tBS0017 = from row in db.TBS0017
where row.Cartao == cartao && row.Data == data
var teste = tBS0017.Select(x => convertToRegisto(x));
public Registo convertToRegisto(TBS0017 x)
{
string term = db.ba_terminal.Where(y => "00"+y.terminal_id.ToString() == x.CodTerminal).Select(y => y.terminal_name).ToString();
string emp = db.TG0006.Where(y => "00"+y.IdCompanhia.ToString() == x.IdCompanhia.ToString()).Select(y => y.DsCompanhia).ToString();
Registo r = new Registo() { Cartao = x.Cartao, Data = x.Data, Hora = x.Hora, Local = term, Empresa = emp };
return r;
}
Bring tBS0017 back into memory with ToList()
var results = tBS0017.ToList()
.Select(x => convertToRegisto(x));
However, this has some serious flaws.
For every element in tBS0017, you are doing 2 more db query's. You should really be doing this in the one query and projecting to Registo
The issue is that using Linq to Entities tries to convert your C# code into equivalent SQL which can run your query. There is no function "convertToRegisto" in SQL so this gives you an exception.
You can solve the issue by using ToList() to bring the result of the query into memory first. Then you're able to use your methods in the Select.
var teste = tBS0017
.ToList()
.Select(x => convertToRegisto(x));
You can not convert int value from linq to sql. You must use the sql function that convert int to string values. On the other hand, in memory handling is quite heavy operation
e.g
string term = db.ba_terminal.Where(y => "00"+
SqlFunctions.StringConvert((double)y.terminal_id) ==
x.CodTerminal).Select(y => y.terminal_name).ToString();

MVC SqlQuery and a 2nd sort

I am re-writing an existing legacy system that uses stored procedures to retrieve the data needed.
The new design will have the normal column sorting and text filtering, but I came across something that has me stumped.
I am able to perform a LINQ query on the retrieved data and get my desired result as follows:
var customerIDParam = new SqlParameter("#customerID", 452);
var result =
db.Database.SqlQuery<InventoryDetail>("map_efs_InventoryDetail #customerID", customerIDParam).ToList();
// this works!
var finalResult1 = from s in result
.Where(s => s.cProductDescription.Contains("E"))
.OrderBy(s => s.cProductDescription)
select s;
return View(finalResult1.ToList());
I would really like to build the LINQ statement dynamically as follows BUT THIS FAILS, always returning the full query
var customerIDParam = new SqlParameter("#customerID", 452);
var result =
db.Database.SqlQuery<InventoryDetail>("map_efs_InventoryDetail #customerID", customerIDParam).ToList();
// This does not work ???
var finalResult2 = from s in result select s;
finalResult2.OrderBy(s => s.cProductDescription);
finalResult2.Where(s => s.cProductDescription.Contains("E"));
return View(finalResult2.ToList());
If anyone can assist I would appreciate it.
Regards
Mark
OrderBy/Where/Etc are "pure" methods, they will return an other IEnumerable, so your result never gets ordered or filtered, you need to assign the new operations (I say operations beacuse IEnumerables have deferred execution), eg:
Assigning variables:
List<Customer> customers = context.Customers.ToList();
IEnumerable<Company> companies = customers.Select(e => e.Company);
IEnumerable<Company> companiesFiltered = companies.Where(e => e.Active);
IOrderedEnumerable<Company> companiesOrdered = companiesFiltered.OrderBy(e => e.Id);
companiesFiltered = companiesOrdered.ThenBy(e => e.Code); // because the variable and result are the same type we can do this
Using returning values:
var finalResult2 = result.Select(r => r.s)
.Where(s => s.cProductDescription.Contains("E"))
.OrderBy(s => s.cProductDescription);
Because every operation returns another IEnumrable we can "chain calls" fluently like that. Remember that actual execution takes place when you call ToList().
I discovered my own error.
var finalResult2 = from s in result select s;
finalResult2 = finalResult2.OrderBy(s => s.cProductDescription);
finalResult2 = finalResult2.Where(s => s.cProductDescription.Contains("E"));
return View(finalResult2.ToList());

LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method when attempting to parse a column for inequality comparisons

I have following code in my page:
var myVar= Entity.SetName
.Where(p => int.Parse(p.ID) >= start &&
int.Parse(p.ID) <= end);
start and end are int, but p.ID is string. So i should convert p.ID to int. But i get following error:
LINQ to Entities does not recognize the method 'Int32
Parse(System.String)' method, and this method cannot be translated
into a store expression.
Where is the problem??
First, I would highly recommend to check your database design, whether there is a really good reason for ID to be a string. I would consider changing the ID DB type to int and you will get rid of this problem with converting.
The error you get means, that EF does not know how to convert the method Int32.Parse() to SQL.
Basically you have two options how to deal with that:
Do the comparison outside the linq to entities:
var myVar= Entity.SetName.AsEnumerable()
.Where(p => int.Parse(p.ID) >= start &&
int.Parse(p.ID) <= end);
But this is not recommended, because you are reading whole result set from DB, before applying the where condition.
Or make custom model defined function as described in this post on SO:
Convert String to Int in EF 4.0
or
Entity Framework: Where do I extend the CSDL/MSL?
First try to convert to int then pass that variable name
int catgry = Convert.ToInt32(customercategory.OWNERSHIP_TYPE);
var customerCateg = (from d in _db.tbl_SIL_CUSTOMER_CATEGORY_MST
.Where(d => d.CAT_ID == catgry) select d.CAT_TYPE).SingleOrDefault();
private void LoadDetail(int id)
{
var sp = from category in db.ProductCategories
join product in db.Products on category.ProductCategoryID equals product.ProductCategoryID
where id == int.Parse(category.ProductCategoryID)
select new
{
product.ProductID,
product.ProductName,
product.ProductCode,
product.Deception,
category.CategoryName,
product.Quanrity,
product.Price
};
DGVDetail.DataSource = sp.ToList();//help: Error: LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method, and this method cannot be translated into a store expression
}
private void DGVMaster_CellClick(object sender, DataGridViewCellEventArgs e)
{
int index = e.RowIndex;
LoadDetail(index + 1);
}
To Convert string to int, you have to make it Enumerable, then you can make sort or anything you like
var list = db.UserEntriesTable.AsEnumerable().Select(x => new {
Name = x.Name,
Roll = Convert.ToInt32(x.Roll),
Mobile = x.Mobile
}).OrderBy(x => x.Roll).ToList();
int nb = EE.Stagaire.Join(EE.Filiere, S => S.IdFiliere, F => F.IdFiliere, (S, F) => new
{
ID = S.Id,
Name = S.Nom,
Prénon = S.Prenon,
Email = S.Email,
MoteDePass = S.MoteDePass,
Filiere = F.Filiere1,
}).Where(S => S.ID.ToString() == r.ToString()).Take(1).Count();
if (nb != 0)
{
MessageBox.Show("find it");
}
//You can do that if you have to data type is integer
Although it's not efficient, you should be able to load all rows, and then use LINQ to Objects:
var myVar= Entity.SetName.ToList()
.Where(p => int.Parse(p.ID) >= start &&
int.Parse(p.ID) <= end);

LINQ Lambda, Group by with list

I'm having some trouble with finding the right syntax to accomplish the following:
Is it possible with LINQ (Lambda Expression) to .GroupBy data and instead of using the usual .Sum() or .Count() I want the resulting data to be a List of Int.
I defined my own class named: Filter_IDs. Its constructor needs two parameters:
public int? type; // Represents the object_type column from my database
public List<int?> objects; // Represents the object_id column from my database
I want to load data from my database into this object. The following LINQ query should result in a List of Filter_IDs:
The following LINQ query should result in a List of Filter_IDs:
List<Filter_IDs> filterids = ef.filterLine
.GroupBy(fl => fl.objectType)
.Select(fl => new Filter_IDs { type = fl.Key, objects = fl.Select(x => x.object_id).ToList() })
.ToList();
Using this query gives no building error but gives an 'NotSupportedException' on RunTime.
The database looks like this to give you a better understanding of the data:
http://d.pr/i/mnhq+ (droplr image)
Thanks in advance,
Gerben
I think the problem is the DB is not able to call ToList in the select, nor to create a new Filter_ID.
Try something like this :
List<Filter_IDs> filterids = ef.filterLine.Select(o => new { objectType = o.objectType, object_id=o.object_id})
.GroupBy(fl => fl.objectType).ToList()
.Select(fl => new Filter_IDs { type = fl.Key, objects = fl.Select(x => x.object_id).ToList() })
.ToList();
Maybe you want
IList<Filter_IDs> filterIds = ef.filterline
.Select(fl => fl.objectType).Distinct()
.Select(ot => new Filter_IDs
{
type = ot,
objects = ef.filterline
.Where(fl => fl.objectType == ot)
.Select(fl =>objectType)
.ToList()
}).ToList();
Get the distinct list objectType and use that to subquery for each list of object_id.
However, it seems more efficient to me to just enumerate the values in order,
var results = new List<Filter_IDs>();
var ids = new List<int>();
var first = true;
int thisType;
foreach (var fl in ef.filterLines
.OrderBy(fl => fl.objectType)
.ThenBy(fl => fl.object_Id))
{
if (first)
{
thisType = fl.objectType;
first = false;
}
else
{
if (fl.objectType == thisType)
{
ids.Add(fl.object_Id);
}
else
{
results.Add(new Filter_IDs
{
Type = thisType,
objects = ids
});
thisType = fl.objectType;
ids = new List<int>();
}
}
}
You can use GroupBy on client side:
List<Filter_IDs> filterids = ef.filterLine
.Select(fl=>new {fl.ObjectType, fl.object_id})
.AsEnumerable()
.GroupBy(fl => fl.objectType)
.Select(fl => new Filter_IDs { type = fl.Key, objects = fl.Select(x => x.object_id).ToList() })
.ToList();

Categories

Resources