Im being a bit lazy in NHibernate and using Session.CreateSqlQuery(...) instead of doing the whole thing with Lambda's. Anyway what struct me is that there seems to be a problem converting some of the types returned from (in this case the MySQL) DB into native .Net tyes.
The query in question looks like this....
IList<Client> allocatableClients =
Session.CreateSQLQuery(
"select clients.id as Id, clients.name as Name, clients.customercode as CustomerCode, clients.superclient as SuperClient, clients.clienttypeid as ClientType " +
...
...
.SetResultTransformer(new NHibernate.Transform.AliasToBeanResultTransformer(typeof(Client))).List<Client>();
The type in the database of SuperClient is a bit(1) and in the Client object the type is a bool.
The error received is:
System.ArgumentException: Object of type 'System.UInt64' cannot be converted to type 'System.Boolean'.
It seems strange that this conversion cannot be completed.
Would be greatful for any ideas.
Thanks.
No need to do any lambdas (even though they are fun!). If Client is a mapped class then you can use the core NHibernate method CreateCriteria<>. It is very simple:
session
.CreateCriteria<Client>()
.List<Client>();
If Client isn't mapped then I would create a property SuperUser_Long and wrap it with SuperUser
Related
Due to a huge and hateful database that I'm not allowed to rationalise, I am forced to create a C# Datalayer generator for my app. I'm pretty much done, using T4 to generate Model classes and Insight.Database repos but I needed to create my User Defined Table Types and Stored Procedures via Sql Management Objects.
What I'm interested in is, can I use a short-circuit parameter when creating via SMO? What I want to replicate is something like this:
CREATE PROCEDURE [dbo].[cip_GetLicenses]
#fldIndex int = null
AS
SELECT [fldIndex]
,[fldLicenceData]
FROM [dbo].[tblLicences]
WHERE (#fldIndex is NULL OR (fldIndex = #fldIndex))
I can construct the body of the sproc relatively easily with a string builder and some column iteration, but creating a parameter is done separately.
The StoredProcedureParameter Type does actually have a DefaultValue property but it's a string, and sadly setting it to " = null" simply throws exceptions at run time.
Can anyone advise?
Recently I read the following post Using a List in a where clause in Entity Framework
And I've tried to do exactly like that. In the example, we have the following code as example:
List<int> docIds = (from d in doc
where d.Tags.All(t => _tags.Contains(t))
select d.id).ToList<int>();
And here, we have my code:
List<PostOrcamentoServico> lOrcamentos = (from orcamento in db.PostOrcamentoServico
where orcamento.Servicos.All(s => usuario.Clientes.Servicos.Contains(s))
select orcamento).ToList();
However, I'm always getting this error:
Unable to create a constant value of type 'Servicili.Models.Servicos'. Only primitive types or enumeration types are supported in this context.
I already tried lamda, LINQ, etc.. but, nothing is working.
The idea is the following: PostOrcamentoServico is like a Budget, where must have one or many kind of services.
On other side, the user logged, register specify all services that he can offer as professional. So, when he tries to search for budget, he can only search for budget of services that the user (professional) offer.
Budget -> One-Many-Services;
2.Professioanl -> One-Many services;
Search = All budgets that has services in the Professional services list.
If the Servicili.Models.Servicos class has a unique identifier, then try this:
var servicios=usuario.Clientes.Servicos.Select(s=>s.Id);
List<PostOrcamentoServico> lOrcamentos = (from orcamento in db.PostOrcamentoServico
where orcamento.Servicos.All(s => servicios.Contains(s.Id))
select orcamento).ToList();
As the exception said you can't use the Contains method with non-primitive values. Only primitive types or enumeration types are supported because they can be translated into SQL.That's way you need to convert your list of services(usuario.Clientes.Servicos) in a collection of an primitive type where you can identify all the services that you want to use to compare. If the Servicos class is an entity of your model, you should have a Id property:
var servicios=usuario.Clientes.Servicos.Select(s=>s.Id);
The error description pretty much nails it: you are using a non primitive type in that Contains statement. The primitive type collections are required because entity framework knows how to translate them into an sql query, like so:
Select Name from Persons where City in ('Berlin', 'Paris', 'Rome');
Now imagine translating non-primitive collection.Contains() into an sql query like the above.
The solution is to build a list of, say, Ids and then use that list.Contains in your other queries, but of course, handing it an id parameter.
EDIT: pretty much like octavio said in his answer.
I'm working on a messaging application that needs to send as part of a message some parameters of C# type "object". My fallback solution is to just serialize the object and store it in the database as a string and deserialize it when necessary.
My question is, what is the general strategy for storing instances of type "object" in SQL using NHibernate?
Write a custom IUserType which handles your serialization issues. It can take your Object and persist it in whatever format you like, e.g. SerializedObjectType nvarchar(max) + SerializedObjectJson nvarchar(max).
See MoneyUserType from NCommon.NHibernate which persist two columns, Amount and Currency.
I'm building dynamic table with stored procedure, so when adding function import, I want it to return object instead of specific type. Is it possible? Thanks
UDPATE
I've tested this and it doesn't work - the call to SqlQuery returns a System.Object. I'll not mark for deletion as it is useful to know that this technique doesn't work.
it should be possible but as #BorisB has said, I'm not sure why you would want to ...
List<dynamic> result = context
.Database
.SqlQuery<dynamic>("select * from ......")
.ToList();
If it were possible what would be the type of that returned object and how would you access its properties?
You'd somehow had to build an EF complex type and a function import at runtime or build a model using ModelBuilder (but you still don't have a data class), which may be possible in theory but it in practice it is way above the problem you are solving.
Maybe it would be better to use ADO.Net directly or modify those SPs to return results as XML which is then consumed by the client (but in XML case you still don't have compiled type of returned objects, so no deserialization, only XPath).
Say I have the following query in LINQPad targeting a SQL DB (using C# Statement(s) mode):
var query = (from te in Time_Entries
select new { te.Period, te.Company_Name }).FirstOrDefault();
If I wanted to update the Period value on the selected record, I would think that I could do something like:
query.Period = 5;
SubmitChanges();
But unfortunately, I get an error on the query.Period assignment line:
Property or indexer 'AnonymousType#1.Period' cannot be assigned to -- it is read only
Is it possible to perform an update this way or in a similar way?
No, you can't. Anonymous types can't have properties that can be modified.
From the documentation:
Anonymous types provide a convenient way to encapsulate a set of
read-only properties into a single object without having to explicitly
define a type first.
It doesn't really make sense anyway. Anonymous types are sometimes very useful, but not when you need to use Linq2Sql entity tracking and updating...
Well, the answer is already in the
select new {}
Even if it would not be an anonymous type, all it could be is an insert....
The rest is answered by walther in his answer.