Adding OrderBy to an EF query causes OutOfMemoryException - c#

EDIT - This only happens when I add OrderBy before the projection. If I add it after the projection, the query is very quick and has no out of memory problem! I used Linq Pad to check the gen'ed SQL. When I do the order by before the projection the SQL is hundreds of lines longer and has far more projections in it than when it after.
Here's a significantly shortened example of sorting pre projection
from contact in Contacts
orderby contact.ContactID
let DefaultAddress = contact.Addresses.FirstOrDefault(x => x.IsDefault.HasValue && x.IsDefault.Value)
select new {
ContactID = contact.ContactID,
DefaultAddressLine2 = DefaultAddress.Line2
}
And the same example, but sorted post projection
from contact in Contacts
let DefaultAddress = contact.Addresses.FirstOrDefault(x => x.IsDefault.HasValue && x.IsDefault.Value)
select new {
ContactID = contact.ContactID,
DefaultAddressLine2 = DefaultAddress.Line2
} into x
orderby x.ContactID
select x
The second example results in a straight SELECT FROM with a single OUTER APPLY for the address. The first results in two OUTER APPLY's. In the full version of the query, this same "doubling" of the outer apply happens exponentially and I end up with hundreds of extra applys!
ORIGINAL - I have a query to return contacts along with their default address, phone number, and e-mail along these lines
from contact in Db.Contacts
select new
{
Contact = contact,
DefaultAddress = contact.Addresses.FirstOrDefault(x => x.IsDefault.HasValue && x.IsDefault.Value),
DefaultPhone = contact.Phones.FirstOrDefault(x => x.IsDefault.HasValue && x.IsDefault.Value),
DefaultEmail = contact.Emails.FirstOrDefault(x => x.IsDefault.HasValue && x.IsDefault.Value)
} into withDefaults
select new ContactWithDefaultsModel
{
ContactID = withDefaults.Contact.ContactID,
Surname = withDefaults.Contact.ESurname,
First = withDefaults.Contact.EFirst,
// other contact props
DefaultAddressLine2 = withDefaults.DefaultAddress != null ? withDefaults.DefaultAddress.Line2 : null,
DefaultAddressCityID = withDefaults.DefaultAddress != null ? withDefaults.DefaultAddress.CityID : null,
DefaultAddressStateID = withDefaults.DefaultAddress != null ? withDefaults.DefaultAddress.StateID : null,
DefaultAddressCountryID = withDefaults.DefaultAddress != null ? withDefaults.DefaultAddress.CountryID : null,
DefaultAddressZip = withDefaults.DefaultAddress != null ? withDefaults.DefaultAddress.Zip : null,
// same for default phone/email
}
That query works fine, but when I add an OrderBy, even for something simple like OrderBy(x => x.ContactID), the query crashes with an OutOfMemoryException.
I can see from the stack trace that it has something to do with the query plan compiler, but I can't see what the cause is. Here's the full stack trace.
at System.Text.StringBuilder.ToString()
at System.Data.Entity.Core.Metadata.Edm.EdmType.get_Identity()
at System.Data.Entity.Core.Metadata.Edm.TypeUsage.BuildIdentity(StringBuilder builder)
at System.Data.Entity.Core.Metadata.Edm.RowType.GetRowTypeIdentityFromProperties(IEnumerable`1 properties, InitializerMetadata initializerMetadata)
at System.Data.Entity.Core.Metadata.Edm.RowType..ctor(IEnumerable`1 properties, InitializerMetadata initializerMetadata)
at System.Data.Entity.Core.Metadata.Edm.TypeUsage.get_ModelTypeUsage()
at System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateProperty(DbExpression instance, String propertyName, Boolean ignoreCase, EdmMember& foundMember)
at System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder.DbExpressionBuilder.PropertyByName(DbExpression instance, String propertyName, Boolean ignoreCase)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.BindingScope.TryResolveVar(Var targetVar, DbExpression& resultExpr)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.ResolveVar(Var referencedVar)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.Visit(VarRefOp op, Node n)
at System.Data.Entity.Core.Query.InternalTrees.VarRefOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Entity.Core.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.Visit(ComparisonOp op, Node n)
at System.Data.Entity.Core.Query.InternalTrees.ComparisonOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Entity.Core.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.Visit(ConditionalOp op, Node n)
at System.Data.Entity.Core.Query.InternalTrees.ConditionalOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Entity.Core.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.Visit(FilterOp op, Node n)
at System.Data.Entity.Core.Query.InternalTrees.FilterOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Entity.Core.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.BuildProjection(Node relOpNode, IEnumerable`1 projectionVars)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.Visit(SingleRowOp op, Node n)
at System.Data.Entity.Core.Query.InternalTrees.SingleRowOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Entity.Core.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.VisitApply(Node applyNode, DbExpressionKind applyKind)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.Visit(OuterApplyOp op, Node n)
at System.Data.Entity.Core.Query.InternalTrees.OuterApplyOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Entity.Core.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.VisitApply(Node applyNode, DbExpressionKind applyKind)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.Visit(OuterApplyOp op, Node n)
at System.Data.Entity.Core.Query.InternalTrees.OuterApplyOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Entity.Core.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.VisitApply(Node applyNode, DbExpressionKind applyKind)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.Visit(OuterApplyOp op, Node n)
at System.Data.Entity.Core.Query.InternalTrees.OuterApplyOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Entity.Core.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.VisitApply(Node applyNode, DbExpressionKind applyKind)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.Visit(OuterApplyOp op, Node n)
at System.Data.Entity.Core.Query.InternalTrees.OuterApplyOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Entity.Core.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node input…tOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Entity.Core.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Entity.Core.Query.PlanCompiler.CTreeGenerator..ctor(Command itree, Node toConvert)
at System.Data.Entity.Core.Query.PlanCompiler.ProviderCommandInfoUtils.Create(Command command, Node node)
at System.Data.Entity.Core.Query.PlanCompiler.CodeGen.Process(List`1& childCommands, ColumnMap& resultColumnMap, Int32& columnCount)
at System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Compile(List`1& providerCommands, ColumnMap& resultColumnMap, Int32& columnCount, Set`1& entitySets)
at System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Compile(DbCommandTree ctree, List`1& providerCommands, ColumnMap& resultColumnMap, Int32& columnCount, Set`1& entitySets)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator)
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)
at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)
at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)
at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Owin.HttpMessageHandlerAdapter.<BufferResponseContentAsync>d__13.MoveNext()

I can't say for sure that this will help, but you're giving the plan compiler an awful lot to do that's not necessary. Removing all redundancies, your query could look like this:
from contact in Db.contacts
let DefaultAddress = contact.Addresses.FirstOrDefault(x => x.IsDefault.Value)
let DefaultPhone = contact.Phones.FirstOrDefault(x => x.IsDefault.Value)
let DefaultEmail = contact.Emails.FirstOrDefault(x => x.IsDefault.Value)
select new contactWithDefaultsModel
{
contactID = contact.contactID,
Surname = contact.ESurname,
First = contact.EFirst,
// other contact props
DefaultAddressLine2 = DefaultAddress.Line2,
DefaultAddressCityID = DefaultAddress.CityID,
DefaultAddressStateID = DefaultAddress.StateID,
DefaultAddressCountryID = DefaultAddress.CountryID,
DefaultAddressZip = DefaultAddress.Zip,
// same for default phone/email
}
Here's what I changed:
Removed the projection to an intermediate anonymous type and replaces this by let calls.
Removed all null checks. This can be done safely, because the entire expression is translated into SQL, which doesn't have a null reference concept. In fact, SQL has null propagation that C# now also has, but without the explicit operator (?). Leaving these null checks here will get them translated into the final SQL query, where they're redundant.
This should give the plan compiler less code to chew on and hopefully skirt around this exception.

This issue occurs because you has insufficient memory to allocate for large results.You could sort the list in place, using List.Sort, which uses the Quicksort algorithm. But of course, your original list would be sorted
Contacts.Sort(x => x.CompareTo(ContactID));

Related

how to fix this query of sql

Address TableUserTableThis Query is working perfectly fine in SQL Server Management Studio.
But when I am trying to run this query in C# it gives an exception please help me.
I Have tried many things but unable to resolve this problem.
SQL QUERY
set #LATITUDE=12
set #LONGITUDE=12
Select * FROM [ChefODine].[dbo].[User] Inner Join [ChefODine].[dbo].[Address] on [ChefODine].[dbo].[User].AID=Address.ID
WHERE AID IN (
SELECT Top 5 ID
FROM [ChefODine].[dbo].[Address]
ORDER BY (ABS(ABS(LAT)-ABS(#LATITUDE)))+ABS(ABS(Lng)-ABS(#LONGITUDE)))
C# CODE
public HttpResponseMessage getNearByChef(double lat, double lng)
{
var user = db.Users.SqlQuery("Select * FROM [ChefODine].[dbo].[User] Inner Join [ChefODine].[dbo].[Address] on [ChefODine].[dbo].[User].AID=Address.ID WHERE AID IN( SELECT Top 5 ID FROM[ChefODine].[dbo].[Address] ORDER BY(ABS(ABS(LAT) - ABS("+lat+"))) + ABS(ABS(Lng) - ABS("+lng+"))) ");
return Request.CreateResponse(HttpStatusCode.OK,user);
}
Here is the Exception:
"Message": "An error has occurred.",
"ExceptionMessage": "The 'ObjectContent'1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": null,
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "The data reader is incompatible with the specified 'ChefODineModel.User'. A member of the type, 'Date_time', does not have a corresponding column in the data reader with the same name.",
"ExceptionType": "System.Data.Entity.Core.EntityCommandExecutionException",
"StackTrace": " at System.Data.Entity.Core.Query.InternalTrees.ColumnMapFactory.GetMemberOrdinalFromReader(DbDataReader storeDataReader, EdmMember member, EdmType currentType, Dictionary'2 renameList)\r\n at System.Data.Entity.Core.Query.InternalTrees.ColumnMapFactory.GetColumnMapsForType(DbDataReader storeDataReader, EdmType edmType, Dictionary'2 renameList)\r\n at System.Data.Entity.Core.Query.InternalTrees.ColumnMapFactory.CreateColumnMapFromReaderAndType(DbDataReader storeDataReader, EdmType edmType, EntitySet entitySet, Dictionary'2 renameList)\r\n at System.Data.Entity.Core.Objects.ObjectContext.InternalTranslate[TElement](DbDataReader reader, String entitySetName, MergeOption mergeOption, Boolean streaming, EntitySet& entitySet, TypeUsage& edmType)\r\n at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters)\r\n at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass65'1.b__64()\r\n at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func'1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)\r\n at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass65'1.b__63()\r\n at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func'1 operation)\r\n at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryReliably[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters)\r\n at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQuery[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters)\r\n at System.Data.Entity.Internal.Linq.InternalSet'1.<>c__DisplayClass11.b__10()\r\n at System.Data.Entity.Internal.LazyEnumerator'1.MoveNext()\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()"
"The data reader is incompatible with the specified
'ChefODineModel.User'. A member of the type, 'Date_time', does not
have a corresponding column in the data reader with the same name.",
The user object cannot be mapped with ChefODineModel.User because date_time doesn't exist in the Dto Model.
beside that you can use SqlParameter when you have to pass data into the query
public HttpResponseMessage getNearByChef(double lat, double lng)
{
string query = #"Select u.* FROM [ChefODine].[dbo].[User] u
Inner Join [ChefODine].[dbo].[Address] on [ChefODine].[dbo].[User].AID=Address.ID
WHERE AID IN( SELECT Top 5 ID FROM[ChefODine].[dbo].[Address] ORDER BY(ABS(ABS(LAT) - ABS(#LATITUDE))) + ABS(ABS(LATITUDE) - ABS(#LONGITUDE)))";
var user = db.Users.SqlQuery(query, new SqlParameter("#LATITUDE", lat), new SqlParameter("#LONGITUDE", lng)).ToList();
return Request.CreateResponse(HttpStatusCode.OK, user);
}

Dapper throws "Invalid type owner for DynamicMethod."

So I'm trying to use Dapper.net and I'm liking it. What I'm not liking is when I try to batch-insert entities and I get the following error thrown:
Invalid type owner for DynamicMethod.
at System.Reflection.Emit.DynamicMethod.Init(String name,
MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] signature, Type owner, Module m, Boolean
skipVisibility, Boolean transparentMethod, StackCrawlMark& stackMark)
at System.Reflection.Emit.DynamicMethod..ctor(String name, Type
returnType, Type[] parameterTypes, Type owner, Boolean skipVisibility)
at Dapper.SqlMapper.CreateParamInfoGenerator(Identity identity,
Boolean checkForDuplicates, Boolean removeUnused, IList1 literals) in
D:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 3033 at
Dapper.SqlMapper.GetCacheInfo(Identity identity, Object
exampleParameters, Boolean addToCache) in D:\Dev\dapper-dot-net\Dapper
NET40\SqlMapper.cs:line 2138 at
Dapper.SqlMapper.<QueryImpl>d__611.MoveNext() in
D:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 1578 at
System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at
Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param,
IDbTransaction transaction, Boolean buffered, Nullable1
commandTimeout, Nullable1 commandType) in
D:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 1479 at
Dapper.SqlMapper.Query(IDbConnection cnn, String sql, Object param,
IDbTransaction transaction, Boolean buffered, Nullable1
commandTimeout, Nullable1 commandType) in
D:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 1418 at
NinjaEvaluation.Data.Database.DapperWrapper.<>c__DisplayClass41.b__3(SqlConnection
sqlConnection, SqlTransaction transaction) in
c:\Projects\InHouse\ninjaevaluation\NinjaEvaluation\NinjaEvaluation.Data\Database\DapperWrapper.cs:line
52 at NinjaEvaluation.Data.Database.DapperWrapper.Invoke(Action`2
action) in
c:\Projects\InHouse\ninjaevaluation\NinjaEvaluation\NinjaEvaluation.Data\Database\DapperWrapper.cs:line
68
This happens in a completely normal situation when I run my query like this:
string sql = #" INSERT INTO XXX
(XXXId, AnotherId, ThirdId, Value, Comment)
VALUES
(#XXXId, #AnotherId, #ThirdId, #Value, #Comment)";
var parameters = command
.MyModels
.Select(model => new
{
XXXId= model.XXXId,
AnotherId= model.AnotherId,
ThirdId= model.ThirdId,
Value = model.Value,
Comment = model.Comment
})
.ToArray();
...
sqlConnection.Query(sql, parameters, commandType: commandType, transaction: transaction)
I found the following SO-thread started by someone having the same problem BUT the issue there seems to have been the .NET version (3.5) but I'm running .NET 4.5 and I can't figure out what the problem is.
Any suggestions?
I ran into this error when using an interface instead of the class:
Query<MyObject> worked, while Query<IMyObject> did not
It fails because this scenario using Query[<T>] isn't expecting an array / sequence of parameters. The Execute call-path does expect this, and unrolls the data automatically, executing the SQL once per item - but this isn't the case for Query[<T>], so it tries to create the dynamic method bound to the array (in your case), which isn't allowed. The code should probably detect this much earlier, and just say "nope, that isn't allowed".
You probably want to change your .ToArray() to .Single().
This will be clearer after the next build; the following passes:
public void SO30435185_InvalidTypeOwner()
{
try {
// not shown for brevity: something very similar to your code
Assert.Fail();
} catch(InvalidOperationException ex)
{
ex.Message.IsEqualTo("An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context");
}
}

"Object reference not set to an instance of an object" - but nothing is null?

Yeah, you probably think; "God, another one?".
Yes, another one.
"Object reference not set to an instance of an object."
I've been working with EF6 lately and after developing for some time, I found that a little bit more optimization was needed. Alot has been reworked without problems, but it seems I can't figure out this one.
In my application I've been using this piece of pseudo code to get items from the database.
DbContext context = new DbContext();
public IEnumerable<string> GetExistingNames(IEnumerable<string> names)
{
foreach(string name in names)
{
string existingName = context.Names.Where(n => n.Name == name).FirstOrDefault();
if(existingName == null) continue;
yield return existingName;
}
}
Note that the DbContext is only there for clarification. It gets disposed when it's needed.
This approach "works" but it would mean that if I had, say, 20 names to look up, I would hit the database for about 20 times. Ouch!
Therefore I started looking for a way to implement a single query. I've found a way, but it's not really working as it should. This is my current approach;
public IEnumerable<string> GetExistingNames(ICollection<string> names)
{
IQueryable<Names> query = context.Names.Where(n => names.Contains(n.Name));
if(query == null) yield break;
foreach(var name in query)
{
yield return name.Name;
}
}
This should, to my knowledge, translate in SELECT ... FROM Names WHERE ... IN (...). However, my application crashes at foreach(var name in query) as soon as it hits name, throwing the feared NullReferenceException.
It does, however, pass if(query == null), meaning the query is not null. At this point, I was confused. How can it not be null, but still throw this error?
I was not sure if the query gets executed if I try to access it with this approach. Therefore, I tried to create a list from the query using ToList(), but this throws the same exception upon creating the list.
It seems like everytime I make a call to query, it gives me a NullReferenceException. However, it still passes if(query == null). So, my question is;
Why is it passing the test, but is it not accessible? Did I misinterpret IQueryable<>? And if I did misinterpret it, how should it be done properly?
EDIT
I have debugged before posting. I know for sure that;
names is not null.
context is not null.
Code calling the function:
//A wrapper for the DbContext. This is only used for some methods
//which require the DbContext
DbContextWrapper wrapper = new DbContextWrapper();
public void ProcessNames(List<string> inputNames)
{
//...
foreach(string existingName in wrapper.GetExistingNames(inputNames))
{
//Do something with the names
}
//...
}
EDIT 2
After some more debugging, I found that the query being created is somewhat different. It is supposed to be;
SELECT `Extent1`.`Name`
FROM `Names` AS `Extent1`
WHERE (`Extent1`.`Name` IN ( #gp1,#gp2))
However, I get this;
System.Data.Entity.Infrastructure.DbQuery<MyDbContext.Names>
As the actual query.
The stack trace;
at MySql.Data.Entity.SqlGenerator.Visit(DbPropertyExpression expression)
at MySql.Data.Entity.SqlGenerator.Visit(DbInExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbInExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SqlGenerator.VisitBinaryExpression(DbExpression left, DbExpression right, String op)
at MySql.Data.Entity.SqlGenerator.Visit(DbAndExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbAndExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SelectGenerator.Visit(DbFilterExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbFilterExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type)
at MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type)
at MySql.Data.Entity.SelectGenerator.Visit(DbProjectExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SelectGenerator.GenerateSQL(DbCommandTree tree)
at MySql.Data.MySqlClient.MySqlProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
at System.Data.Entity.Core.Common.DbProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator)
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at MyNameSpace.DbContextWrapper.<GetExistingNames>d__1b.MoveNext() in c:~omitted~\DbContextWrapper.cs:line 70
at MyNameSpace.NameProcessor.ProcessNames(List<string> inputNames) in c:~omitted~\NameProcessor.cs:line 60
After you posted stacktrace I spotted that you using MySQL and so my guess is that you hit this bug: Exception when using IEnumera.Contains(model.property) in Where predicate
So solution would be to ensure you have versions of MySQL Connector/NET 6.7.6 / 6.8.4 / 6.9.5 and newer.
Or try to use Any method instead of Contains.
P.s. This bug report came from this post by Alnedru: Int[].Contains doesn't work in EF6
Your null check on query will never fail, because it's returning the IQueryable object (that is, the query being built). You've instantiated it and started building a query, so it will always pass.
To be clear - IQueryable is roughly equivalent to a string containing the ADO.Net Select statement. It is not, inherently, the actual data.
This doesn't explain why it's throwing a null exception, but it does explain why the null check passes, and the foreach could still fail.
EDIT: When attempting to duplicate this, I found that I get an exception when using the below code:
public IEnumerable<string> GetExistingNames(ICollection<string> names)
{
IQueryable<Names> query = Names.Where(n => names.Contains(n.Name));
if (query == null) yield break;
foreach (var name in query)
{
yield return name.Name;
}
}
It wasn't a NullReferenceException, but a NotSupportedException, as ICollections Contains has no supported translation to SQL. Switching the parameter to List caused the problem to disappear:
public IEnumerable<string> GetExistingNames(List<string> names)
Or you can convert it to a list on the fly:
IQueryable<Names> query = Names.Where(n => names.ToList().Contains(n.Name));
Why don't you just add an extension method to alleviate the stress this brings you.
try this piece of code
namespace HelperExtensionMethods
{
public static class ExtensionMethods
{
public static string UpdateNullString(this string testNullstring)
{
if (TestNullstring == null)
return "";
return Testullstring;
}
}
}
and then call it like so
using HelperExtesionMethods
DbContext context = new DbContext();
public IEnumerable<string> GetExistingNames(ICollection<string> names)
{
IQueryable<Names> query = context.Names.Where(n => names.UpdateNullString().Contains(n.Name.UpdateNullString()));
if(query == null) yield break;
foreach(var name in query)
{
yield return name.Name;
}
}

Int[].Contains doesn't work in EF6

I have a strange issue, basically i have this code:
var langauges = (from l in context.languages
where Model.LanguageIDs.Contains(l.LanguageID)
select l)
.ToList<language>();
I don't know why but I Always get an error:
System.NullReferenceException: Object reference not set to an instance of an object
The thing is it was working before, but after that i've upgraded all my application to MVC5 and EF6, it started to crash on this code.
Although if I check the Model.Langauges, it has several ID's so it is ok.
I also looped through tall the context.Languages and all of them have id's.
I also wrote like this:
var langauges = (from l in context.languages
where 1==l.LanguageID
select l)
.ToList<language>();
And this WORKS also, so i really don't get it, what am i doing wrong?
Anyone can elaborate ...?
StackTrace:
at MySql.Data.Entity.SqlGenerator.Visit(DbPropertyExpression expression)
at MySql.Data.Entity.SqlGenerator.Visit(DbInExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbInExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SqlGenerator.VisitBinaryExpression(DbExpression left, DbExpression right, String op)
at MySql.Data.Entity.SqlGenerator.Visit(DbAndExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbAndExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SelectGenerator.Visit(DbFilterExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbFilterExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type)
at MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type)
at MySql.Data.Entity.SelectGenerator.Visit(DbProjectExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SelectGenerator.GenerateSQL(DbCommandTree tree)
at MySql.Data.MySqlClient.MySqlProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
at System.Data.Entity.Core.Common.DbProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator)
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassb.<GetResults>b__a()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassb.<GetResults>b__9()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at System.Lazy`1.get_Value()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at MyProject.Infrastructure.DAL.Operations.UpdateUserinfo(Int32 id, Model Model) in :line 168
Is it possible that Model.LanguageIDs is null or your context has not yet been setup?
Also, do you allow for null language entries in context.languages? If anyone of those is null, you'll get this exception.
Ok, i am faced exact same problem, but found solution which might help you.
In my case LanguageIDs collection type was List<long>(unisgned int in DB), and LanguageID was int. And this type difference caused problem.
I know, that it's still a bug, and from .net point of view it's absolutely correct, but hope my post will help somebody

Using Any LINQ function to set model property

I have a model:
public class MyModel {
int id { get; set; }
bool selected { get; set; }
}
In my view (which inherits IEnumerable<MyModel>) I call:
Html.EditorForModel()
This calls the subview (or whatever its called) and it displays a hidden field for the id and a checkbox for the selected bool.
I want to be able to pass in some checkboxes as already selected, so in my controller I am doing:
MyModel newmod = new MyModel { Id = 5, selected = (userselections.Any(t=> t.PlayerId == x.id) == true) };
Where userselections is a List of bojects with a PlayerId property.
However, I get the error:
Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
Edit
This how userselections is populated:
var userselections = selectionRepository.Selection.Where(t => t.TeamId == curUser.TeamId).ToList();
Stack Trace
[NotSupportedException: Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.]
System.Data.Linq.SqlClient.QueryConverter.CoerceToSequence(SqlNode node) +901537
System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) +5897
System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc) +70
System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +1025
System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) +30
System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b) +27
System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +449
System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) +30
System.Data.Linq.SqlClient.QueryConverter.VisitMemberInit(MemberInitExpression init) +449
System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +222
System.Data.Linq.SqlClient.QueryConverter.VisitSelect(Expression sequence, LambdaExpression selector) +160
System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) +1419
System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc) +70
System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) +1025
System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(Expression node) +111
System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations) +114
System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) +132
System.Data.Linq.DataQuery`1.System.Collections.IEnumerable.GetEnumerator() +32
System.Web.Mvc.Html.DefaultEditorTemplates.CollectionTemplate(HtmlHelper html, TemplateHelperDelegate templateHelper) +896
System.Web.Mvc.Html.DefaultEditorTemplates.CollectionTemplate(HtmlHelper html) +68
System.Web.Mvc.Html.TemplateHelpers.ExecuteTemplate(HtmlHelper html, ViewDataDictionary viewData, String templateName, DataBoundControlMode mode, GetViewNamesDelegate getViewNames) +1594
System.Web.Mvc.Html.TemplateHelpers.TemplateHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName, String templateName, DataBoundControlMode mode, Object additionalViewData, ExecuteTemplateDelegate executeTemplate) +1616
System.Web.Mvc.Html.TemplateHelpers.TemplateHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName, String templateName, DataBoundControlMode mode, Object additionalViewData) +86
System.Web.Mvc.Html.EditorExtensions.EditorForModel(HtmlHelper html) +91'
(Sorry, not sure how exactly format that. I've cut out all the stuff at the start, before System.Web.Mvc is called).
How about using Contains ?
selected = (userselections.Select(t => t.PlayerID).ToList().Contains(x.id) == true)
Add .ToList() to your query to force it to be sent immediately to the client.

Categories