How does c# interpret my query? - c#

Why does:
var allShapes = _context.AttributeValuesLibraries.Where(x => x.AttNameID.Equals(1)).Select(y => y);
work, but I get the error "Unable to create a constant value of type 'System.Object'. Only primitive types or enumeration types are supported in this context" when I exclude the Select() like:
var allShapes = _context.AttributeValuesLibraries.Where(x => x.AttNameID.Equals(1));
Is there another way to write this query so it makes more sense? I just played with the query to make it work.
Thanks in advance!

Try this:
var allShapes = _context.AttributeValuesLibraries.Where(x => x.AttNameID == 1);
It really depends on your Linq provider.

Related

How get relationship's startNodeId and endNodeId using Neo4jClient?

var query = client.Cypher
.Match("(n1)-[r]-[n2]")
.Where("n1.NodeId={startNodeId} and n2.NodeId={endNodeId}")
.WithParam("startNodeId",startNodeId)
.withParam("endNodeId",endNodeId)
.return((r,n1,n2)=>new {Edge=r.As<Node<string>>(),Type=r.Type()});
By this way,I can only get the relationship's Label and Properties.But I also want to get the relationship's startNodeId and endNodeId.
By the way,I can get the relationship's startNodeId and endNodeId by using REST API.
How can anyone help me?
Z.Tom
It depends on what you're meaning by startNodeId - if you mean the Neo4j Ids, then you'll be wanting to use the Relationship<T> class:
client.Cypher
.Match("(n1)-[r]-(n2)")
//Your where stuff here.
.Return(r => r.As<RelationshipInstance<string>());
The T should be a type you've put on the relationship, but if you haven't got that, just use object, you will need to use the Relationship<T> type, you can't use the non-generic version.
If the startNodeId is a property on a type, then you either do r => r.As<YourType>() or r => r.As<Relationship<YourType>>().
As a side note, you can use Neo4jClients ability to parse parameters and save some code (also make it more compile safe) with respect to your Where clauses.
I would write your code as:
var query = client.Cypher
.Match("(n1)-[r]-[n2]")
.Where((NodeType n1) => n1.NodeId == startNodeId)
.AndWhere((NodeType n2) => n2.NodeId == endNodeId)
.Return(r => new { Edge = r.As<RelationshipInstance<object>>(), Type = r.Type()});
which auto parses the parameters.
If you know the classes which you want to cast to you can use:
var results= client.Cypher
.Match("(n1)-[r]-[n2]")
.Where("n1.NodeId={startNodeId} and n2.NodeId={endNodeId}")
.WithParam("startNodeId",startNodeId)
.withParam("endNodeId",endNodeId)
.Return((n1, r1 n2) => new {Edge=r.As<Node<string>>(),Type=r.Type()}, Class1= n1.As<Class1>(), Class2= n2.As<Class2>()})
.Results;
Then you can iterate through the results. If only one result is expected its first item in the 'results' array

Comparing with where clause using Dictionary<int,int> [duplicate]

This piece of code keep making this error. :
Unable to create a constant value of type 'Repository.DBModel.Subscriber'. Only primitive types or enumeration types are supported in this context.
I've Changed it a few times but it keeps coming up with this Error.
using (SubscriberDBHandler db = new SubscriberDBHandler())
{
IEnumerable <Subscriber> NewSubscribers = Subscribers
.Where(sub => db.Subscriber
.Any(aSub => !aSub.Email.Equals(sub.Email)));
List<Subscriber> updateSubscribers = db.Subscriber
.Where(dbSub => Subscribers
.Any(lSub => lSub.Email
.Equals(dbSub.Email))).ToList();
if(NewSubscribers.Count() >= 1)
{
db.Subscriber.AddRange(NewSubscribers);
}
updateSubscribers.ForEach(aSub => aSub.State = Subscribers
.FirstOrDefault(sub => sub.Email
.Equals(aSub.Email)).State ?? "Error" );
db.SaveChanges();
}
I'd greatly appreciate if someone could point out my error or come up with a more efficient way to do this.
In advance thanks for your time and help.
I know there are a few post with this error out there but when reading them I can't figure out how they relate to my problem. so I'm sorry if this is a common mistake and others have provided a solution
The object Subscribers is a List<Subscriber>
I don't seem to be able to find the line but. the stack trace does contain this.
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
at Repository.SubScribRepository.AddOrUpdateSubscribers(List1 Subscribers)
You use a local collection, Subscribers, directly in a LINQ statement. But these objects can't be translated into SQL. There are only mappings from primitive types to database types.
I'd suggest you use
var emails = Subscribers.Select(s => s.Email).ToList();
And proceed by using these strings (i.e. primitive values) in Contains statements like:
var newSubscribers = db.Subscriber
.Where(dbSub => !emails.Contains(dbSub.Email))
.ToList();
var updateSubscribers = db.Subscriber
.Where(dbSub => emails.Contains(dbSub.Email))
.ToList();
Changing updateSubscribers to an IEnumerable will prevent this error

Error: Only primitive types or enumeration types are supported in this context EF

This piece of code keep making this error. :
Unable to create a constant value of type 'Repository.DBModel.Subscriber'. Only primitive types or enumeration types are supported in this context.
I've Changed it a few times but it keeps coming up with this Error.
using (SubscriberDBHandler db = new SubscriberDBHandler())
{
IEnumerable <Subscriber> NewSubscribers = Subscribers
.Where(sub => db.Subscriber
.Any(aSub => !aSub.Email.Equals(sub.Email)));
List<Subscriber> updateSubscribers = db.Subscriber
.Where(dbSub => Subscribers
.Any(lSub => lSub.Email
.Equals(dbSub.Email))).ToList();
if(NewSubscribers.Count() >= 1)
{
db.Subscriber.AddRange(NewSubscribers);
}
updateSubscribers.ForEach(aSub => aSub.State = Subscribers
.FirstOrDefault(sub => sub.Email
.Equals(aSub.Email)).State ?? "Error" );
db.SaveChanges();
}
I'd greatly appreciate if someone could point out my error or come up with a more efficient way to do this.
In advance thanks for your time and help.
I know there are a few post with this error out there but when reading them I can't figure out how they relate to my problem. so I'm sorry if this is a common mistake and others have provided a solution
The object Subscribers is a List<Subscriber>
I don't seem to be able to find the line but. the stack trace does contain this.
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
at Repository.SubScribRepository.AddOrUpdateSubscribers(List1 Subscribers)
You use a local collection, Subscribers, directly in a LINQ statement. But these objects can't be translated into SQL. There are only mappings from primitive types to database types.
I'd suggest you use
var emails = Subscribers.Select(s => s.Email).ToList();
And proceed by using these strings (i.e. primitive values) in Contains statements like:
var newSubscribers = db.Subscriber
.Where(dbSub => !emails.Contains(dbSub.Email))
.ToList();
var updateSubscribers = db.Subscriber
.Where(dbSub => emails.Contains(dbSub.Email))
.ToList();
Changing updateSubscribers to an IEnumerable will prevent this error

Unable to create a constant value of type 'System.Char' in MVC

I have a code segment like the following:
var results = business.Where(b => b.Description.ToLower().Contains(request.ServiceName.ToLower()));
var bb = results.Where(r => !r.Zip.Contains('-'));
When I ran this I get an error message in the title. My queries return a complex type that I have defined, and one of the properties' of that complex type is:
public string Zip { get; set; }
I want to exclude all the entries that does not include dash in the zip part.
It should be double quote ...Contains("-").
var bb = results.Where(r => !r.Zip.Contains("-"));
In addition, you can combine two where clauses into one if you only care about final result.
var results = business.Where(b =>
b.Description.ToLower().Contains(request.ServiceName.ToLower()) &&
!b.Zip.Contains("-"));
FYI: If you use Entity Framework, you do not need ToLower().
Assuming this is an Entity Framework query, Char is not a primitive type, hence the error. Try var bb = results.Where(r => !r.Zip.Contains("-"));
Found a similar (duplicate) here: Why does this LinQ query not like chars?

Lambda expression compare boolean as false results in NotSupportedException

I can't seem to figure out how to compare boolean values in a C# lambda expression for EF4. I've tried:
cl.Where(c => c.Received == false);
and this:
cl.Where(c => !c.Received);
and this:
cl.Where(c => c.Received.Equals(false));
but I keep getting this error:
Exception Details: System.NotSupportedException: Unable to create a constant value
of type 'System.Object'. Only primitive types ('such as Int32, String, and Guid')
are supported in this context.
After spending a good amount of time researching this I'm still missing something. I'm fairly new to Lambdas so pointers would be appreciated.
Edit2: more code re:comment
int bar = 42;
var cl = db.foo.Where(c => c.baz.Equals(bar));
//codez (just an if statement)
cl.Where(c => c.Received == false).OrderByDescending(c => c.dateAdded);
That's it. Even if I remove the orderby it still doesn't work
Edit3:
Solution:
int bar = 42;
var cl = db.foo.Where(c => c.baz == bar);
cl.Where(c => c.Received == false).OrderByDescending(c => c.dateAdded);
The issue is most likely in the c.baz.Equals(bar) line. If you change it to
var cl = db.foo.Where(c => c.baz.Equals(bar)).ToList();
you should see the exception thrown on that line, because you force evaluation of the IQueryable<T>.
Instead of comparing objects, you should compare their IDs, like this:
(edited to reflect the conversation in the comments and changes to the OP)
var cl = db.foo.Where(c => c.baz == bar.id);
What is the type of Received ? Where close need a predicate(a function that return Boolean) in order to act upon every element in the list and return those that satisfy the condition. From the error message it seems the Received in not primitive type. You need to cast it to boolean if you for sure know its boolean.

Categories

Resources