MySql Linq to SQL conver int to string - c#

Hello I have a MySQL and LINQ to SQL task to convert Int value from DB to String,
toString() is not supported by MySql, and I am getting error about it.
var data = (from o in ObjectContext.MyTable.Where(d => d.a == a)
select new MyObject
{
Id = o.Id,
StringProperty = o.intColumn.ToString()
});
SqlFunction class is not suported for MySql.

You can try to convert the results to Enumerable and then query on it:
var data = (from o in ObjectContext.MyTable.Where(d => d.a == a)
select new MyObject
{
Id = o.Id,
StringProperty = o.intColumn.ToString()
}).AsEnumerable();

You could fetch all the data by adding AsEnumerable() to the table, or you could do the fetch first, then the conversion later - if I'm not mistaken, this should produce a slightly lighter SQL call:
var tempData = (from o in ObjectContext.Where(d => d.a == a) select o);
var converted = (from o in tempData.AsEnumerable()
select new MyObject
{
Id = o.Id,
StringProperty = o.intColumn.ToString()
});
Alternatively, write it all in one go by using the first part as a sub query:
var data = from x in
(from o in ObjectContext.Where(d => d.a == a) select o)
.AsEnumerable()
select new MyObject
{
Id = x.Id,
StringProperty = x.intColumn.ToString()
});

int to string in Entity Framework
also had supported a great solution you can refer. By this method you can change you source as the following.
var data = (from o in ObjectContext.MyTable.Where(d => d.a == a)
select new MyObject
{
Id = o.Id,
StringProperty = SqlFunctions.StringConvert((double)o.intColumn)
});

Related

c# return named tuple from linq join

i'am trying to perform a join between a revision entity from nhibernate envers and a list with user names. i want to return a list of named tuples.
this is my code
public IEnumerable<(Societa company, DateTime datetime, string userName)> CompanyHistory()
{
IAuditReader auditReader = this._session.Auditer();
var revison = auditReader.CreateQuery().ForHistoryOf<Societa, RevisionEntity>().Results();
IList<Persona> user = _session.QueryOver<Persona>().List();
var query = revison.Join(user,
rev => rev.RevisionEntity.IdUtente,
us => us.Id,
(rev, us) => new
{
Oggetto = rev.RevisionEntity,
DataModifica = rev.RevisionEntity.RevisionDate.ToLocalTime(),
NomeUtente = us.NomePersona
}).ToList();
}
but now i didn't find a way to return the tuple
cast didn't work
ToValueTuple is not avaible to fro my query object
i try also
(ele, p) => new (OutputGA Oggetto, DateTime DataModifica, string NomeUtente)
{
Oggetto = ele.RevisionEntity,
DataModifica = ele.RevisionEntity.RevisionDate.ToLocalTime(),
NomeUtente = p.NomePersona
}).ToList();
but i got new cannot be used with tuple type
than
(ele, p) => new Tuple<OutputGA, DateTime, string>
{
Oggetto = ele.RevisionEntity,
DataModifica = ele.RevisionEntity.RevisionDate.ToLocalTime(),
NomeUtente = p.NomePersona
}).ToList();
and got error about parameter not corresponding
You can try this
var tuples = data.Select(x => (A: x.A, B: x.B));
I think the correct syntax should be
(ele, p) =>
(
Oggetto: ele.RevisionEntity,
DataModifica: ele.RevisionEntity.RevisionDate.ToLocalTime(),
NomeUtente: p.NomePersona
)).ToList();

LINQ Data Sorting

I am trying to fill select tag options from JQuery ajax call. I am using Asp.Net Core 2.1 Razor Pages, and PostgreSQL as DB.
Here is my Server side LINQ code
[HttpGet]
public ActionResult TypeofAccounts()
{
var result = (from N in _POSContext.TypeOfAccounts
select new { label = N.AccountType, id = N.AccountType });
return Json(result);
}
It works fine. Now, I want to sort those results from LINQ so I tried following ways but it always encounters Npgsql Exception "column \"label\" does not exist"
var result = (from N in _POSContext.TypeOfAccounts.OrderBy(x=>x.AccountType)
select new { label = N.AccountType, id = N.AccountType });
var result = (from N in _POSContext.TypeOfAccounts
select new { label = N.AccountType, id = N.AccountType }).OrderBy(x => x.label);
var result = (from N in _POSContext.TypeOfAccounts.OrderBy(x => x.AccountType)
where N.AccountType != null
select new { label = N.AccountType, id = N.AccountType });
I could see coloumn is missing in generated sql.
{SELECT x."AccountType" AS id
FROM "TypeOfAccounts" AS x
WHERE x."AccountType" IS NOT NULL
ORDER BY label}
You need to invoke the query from the database using ToList method, then selecting your object, like this:
var result = _POSContext.TypeOfAccounts
.Where(x => x.AccountType != null)
.OrderBy(x => x.AccountType)
.ToList()
.Select(x =>
new
{
label = x.AccountType,
id = x.AccountType
}
);
You can try this
var result = _POSContext.TypeOfAccounts
.Where(x => x.AccountType != null)
.OrderBy(x => x.AccountType)
.ToList()
.Select(x =>
new
{
label = x.AccountType,
id = x.AccountType
}
);

Performing GroupBy and Union using LINQ to fetch records

Here's the situation.
I am trying to perform a Union between two queries using LINQ. I have applied GroupBy in both queries, using anonymous types. I dont know exactly, but probably the usage of anonymous type is leading me to this issue where I am unable to perform that Union operation. It shows me exception like this :
'System.Linq.IQueryable' does not contain a
definition for 'Union' and the best extension method overload
'System.Linq.ParallelEnumerable.Union(System.Linq.ParallelQuery,
System.Collections.Generic.IEnumerable)' has some invalid
arguments
Here is the query :
var records = (from o in _context.Table1
join q in _context.Table2 on o.UserId equals q.UserId
group new { o, q }
by new { o.Name, o.Date, o.IsDone, o.IsDl, o.DateChanged, o.UserId, q.FirstName, q.LastName } into data
select new
{
NameP = data.Key.Name,
Date = data.Key.Date,
IsDone = data.Key.IsDone,
IsDl = data.Key.IsDl,
DateDone = data.Key.DateChanged,
Name = data.Key.FirstName +" "+ data.Key.LastName
}).Union(
from i in _context.Table1
where i.UserId == null
group i by new {o.Name, o.Date, o.IsDone, o.IsDl, o.DateChanged, o.UserId} into newData
select new
{
NameP = newData.Key.Name,
Date= newData.Key.Date,
IsDone = newData.Key.IsDone,
IsDl = newData.Key.IsDl,
DateDone = ' ',
Name = ' '
}).ToList();
What I am trying to achieve here is to get records of both cases, when UserId is null as well as when its not null using group by since records are repeated.
Any suggestions or guidance here on what I am doing wrong are appreciated.
Make sure that the two anonymous types have the same data type for all proprties.
The only ones I can speculate on are the date ones. Maybe the first DateDone is actually a DateTime type and you are setting the second one to a string...
var records = (from o in _context.Table1
join q in _context.Table2 on o.UserId equals q.UserId
group new { o, q }
by new
{
o.Name,
o.Date,
o.IsDone,
o.IsDl,
o.DateChanged,
o.UserId,
q.FirstName,
q.LastName
} into data
select new
{
NameP = data.Key.Name,
Date = data.Key.Date,
IsDone = data.Key.IsDone,
IsDl = data.Key.IsDl,
DateDone = data.Key.DateChanged,
Name = data.Key.FirstName +" "+ data.Key.LastName
}).Union(from i in _context.Table1
where i.UserId == null
group i by new
{
o.Name,
o.Date,
o.IsDone,
o.IsDl,
o.DateChanged,
o.UserId
} into newData
select new
{
NameP = newData.Key.Name,
Date = newData.Key.Date,
IsDone = newData.Key.IsDone,
IsDl = newData.Key.IsDl,
DateDone = new DateTime(0),
Name = ' '
}).ToList();

Getting specific columns from an INCLUDE statement with EF

I want to get only specific columns from a query in EF when using an INCLUDE statement instead of bringing back all the columns.
In addition, what if I also wanted to bring back a shorter result set from my Customers object as well.
Is there a way to do this?
Here is my query:
void Main()
{
IEnumerable<Customer> customerProjectsList = GetCustomerProjects();
customerProjectsList.Dump();
}
public List<Customer> GetCustomerProjects()
{
try
{
using (YeagerTech DbContext = new YeagerTech())
{
var customer = DbContext.Customers.Include("Projects");
return customer;
}
}
catch (Exception ex)
{
throw ex;
}
}
EDIT
I've been trying to use the following query, but get an error of "Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Collections.Generic.ICollection'. An explicit conversion exists (are you missing a cast?)"
Here is the query:
void Main()
{
List customerProjectsList = GetCustomerProjects();
customerProjectsList.Dump();
}
public List<CustomerDTO> GetCustomerProjects()
{
try
{
using (YeagerTech DbContext = new YeagerTech())
{
var customerlist = DbContext.Customers.Select(s =>
new CustomerDTO()
{
CustomerID = s.CustomerID,
Projects =
from p in Projects
where p.CustomerID == s.CustomerID && p.Quote != null
select new Project { Description = p.Description, Quote = p.Quote }
}).ToList<Project>();
return customerlist.ToList();
}
}
catch (Exception ex)
{
throw ex;
}
}
If I run this same query in LINQPad as a C# statement instead of a C# program, the query results get produced fine.
I am just going bonkers over this simple way to try and get a hierarchal list back with specific columns.
var result = (from c in Customers
select new
{
c.CustomerID,
Projects =
from p in Projects
where p.CustomerID == c.CustomerID && p.Quote != null
select new { p.Description, p.Quote }
});
result.Dump();
You don't necessarily need include; if you have navigation properties between Customers and Projects you can project to new objects:
var customers = (from c in DbContext.Customers
select new
{
FirstName = c.FirstName,
ProjectName = c.Project.Name
}).ToList().Select(x => new Customer
{
FirstName = x.FirstName,
Project = new Project()
{
Name = x.ProjectName
}
}).ToList();
This will return a list of Customers where only the first name is populated and each customer will contain a Project property with the name populated. This is great for performance as the query sent by EF to your database will be short and will return a result set quickly.
Edit:
Taking into account that Projects is an ICollection, I think the most maintenable thing to do would be to create a couple of DTOs:
public CustomerDTO
{
public int CustomerId;
public List<ProjectDTO> projects;
}
public ProjectDTO
{
public string Description;
public string Quote;
}
and project to them like so:
var qry = (from c in context.Customers
select new CustomerDTO()
{
CustomerId = c.CustomerId,
Projects = (from pr in context.Projects
where c.ProjectId equals pr.Id
select new ProjectDTO
{
Description = pr.Description,
Quote = pr.Quote
}).ToList()
});
You have to use projection to limit the columns that are retrieved. Lots of examples of projection can be found on the internet a short example is like this :
DateTime twoDaysAgo = DateTime.Now.AddDays(-2);
var groupSummaries = _recipeContext.Groups.OrderBy(g => g.Name)
.Select(g => new GroupSummaryModel{
Id = g.Id,
Name = g.Name,
Description = g.Description,
NumberOfUsers = g.Users.Count(),
NumberOfNewRecipes = g.Recipes.Count(r => r.PostedOn > twoDaysAgo)
});
I took it from here :
http://www.davepaquette.com/archive/2013/02/09/writing-efficient-queries-with-entity-framework-code-first-part-2.aspx
The point is to use the new mechanism if needed multiple times. Here it is used with new GroupSummaryModel.
EDIT
var qry = (from c in context.Customers
select new CustomerDTO()
{
CustomerId = c.CustomerId,
Projects = (from pr in context.Projects
where c.ProjectId equals pr.Id
select new ProjectDTO
{
Description = pr.Description,
Quote = pr.Quote
}) //--> no tolist here
}).ToList(); //--> only here

expression cannot be translate into store expression

I have to download some complex datas from database which aggregate lots of usefull infos about post. I would like to do something like this:
var list = (from message in db.BLOGS_MESSAGES
where message.BLOG_ID == blogId
orderby message.CREATED_DATE descending
select new BlogMessage()
{
AUTHORS = **(from author in message.AUTHORS
select author.USERS).ToArray()**,
CREATED_BY = message.CREATED_BY,
CREATED_DATE = message.CREATED_DATE,
BLOG_MESSAGE_ID = message.POST_ID,
MESSAGE_TITLE = message.TITLES.TITLE,
TAGS = **(from tag in message.TAGGED_MESSAGES
select tag.TAGS).ToArray()**,
LOGIN = message.USERS.LOGIN,
MESSAGE = message.MESSAGES.MESSAGE,
MESSAGE_ID = message.MESSAGE_ID,
POST_NOTE = message.POST_NOTES.Sum(x => (long?)x.NOTE) ?? 0 / message.POST_NOTES.Count(),
}).ToList();
but it doesn't work. It throws an exception that can't translate expression in store expression.
so far i did it in this way:
var mlist = (from message in db.BLOGS_MESSAGES
where ....
orderby ....
select new {
AUTHORS = (from author in message.AUTHORS
select author.USERS),
....
}
List<BlogMessage> list = new List<BlogMessage>();
foreach(var item in mlist)
{
list.Add(new BlogMessage()
{
AUTHORS = item.AUTHORS.ToArray(),
...
});
}
is it possible to make it work 'in first way - style'?
You can either:
Change BlogMessage.AUTHORS to be an IEnumerable<USERS> and remove the .ToArray() calls in the query like Grundy suggested.
Bring the results into memory before creating BlogMessage's.
For example:
var step1 = db.BLOGS_MESSAGES
.Where(...)
.Select(message => new {
Authors = message.AUTHORS.Select(a => a.USERS), // No .ToArray()
...
}).ToList();
var step2 = step1.Select(message => New BlogMessage {
Authors = message.Authors.ToArray(),
...
}).ToList();

Categories