InvalidOperation in T4 Generated Helper Method SelfTrackingModel.Context.Extensions - entity-framework-4.1

I have a project whereby I'm using STE's (EF4.1) and I'm hitting a reproducable issue when I call the auto generated ApplyChanges() method on one of my object sets, passing in an object graph I have held in memory, and I'm getting the following error:
InvalidOperationException:
Collection was modified; enumeration operation may not execute.
This is originating from within a call to ObjectContext.AddObject() method, which is being called by the T4 auto generated ApplyChanges() method. My method to call ApplyChanges looks something like this:
// Extension to auto generated Session : IObjectWithChangeTracker
public partial class Session
{
public void SaveToDatabase(String myConnectionString)
{
using (MyContext DbContext = new MyContext(myConnectionString))
{
DbContext.Sessions.ApplyChanges(this);
DbContext.SaveChanges();
}
}
}
The call stack when I hit the error looks something like this:
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.AddGraphToObjectStateManager(IEntityWrapper wrappedEntity, Boolean relationshipAlreadyExists, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.EntityReference`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)
... // The below 4 lines are pretty much repeated as it iterates through the object graph
at System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.AddGraphToObjectStateManager(IEntityWrapper wrappedEntity, Boolean relationshipAlreadyExists, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.EntityCollection`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.AddGraphToObjectStateManager(IEntityWrapper wrappedEntity, Boolean relationshipAlreadyExists, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.EntityReference`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)
at System.Data.Objects.DataClasses.RelationshipManager.AddRelatedEntitiesToObjectStateManager(Boolean doAttach)
at System.Data.Objects.ObjectContext.AddObject(String entitySetName, Object entity)
at MyNamespace.SelfTrackingEntitiesContextExtensions.AddHelper.AddAllEntities(ObjectContext context, String entitySetName, IObjectWithChangeTracker entity)
at MyNamespace.SelfTrackingEntitiesContextExtensions.ApplyChanges[TEntity](ObjectContext context, String entitySetName, TEntity entity)
at MyNamespace.SelfTrackingEntitiesContextExtensions.ApplyChanges[TEntity](ObjectSet`1 objectSet, TEntity entity)
at MyNamespace.Transaction.SaveToDatabase(String transactionDbConnectionString)
I'm not modifying the object graph at all whilst the operation is in progress, so I'm really stumped as to the issue. Anybody got any ideas?
Thanks

We had the same problem.
We could solve it with removing Navigation properties so that they cannot run in circles.
So if A has B as a Navigation Property, B should not hav A as a Navigation property.
It is not possible under all circumstances but in our case, it solved the problem.

Had the same problem. Looks like a bug that was fixed in .net 4.5.

Related

Spring Jpa Projection interface occur error with Boolean type

Q. Why JPA Projection can't convert Mysql bit(1) to Java Boolean?
Spring Jpa Projection occur error Projection type must be an interface! when the Mysql bit(1) type maps to the Java Boolean type.
Jpa converts a Boolean column in Entity class to bit(1) column in Mysql Table.
If I change getIsBasic's type in PlanInfoProjection interface Integer to Boolean, It doesn't work. Why does it occur error?
JPA Repository
#Query(nativeQuery=true, value="select true as isBasic from dual")
ProductOrderDto.PlanInfoProjection findPlanInfoById(Long id);
Projection interface
public class ProductOrderDto {
#Getter
public static class PlanInfo {
private Boolean isBasic;
public PlanInfo(PlanInfoProjection projection) {
// this.isBasic = projection.getIsBasic(); //<-- I want to use like this.
if (projection.getIsBasic() == null) {
this.isBasic = null;
} else {
this.isBasic = projection.getIsBasic() == 0 ? false : true; // <-- I have to convert
}
}
}
public interface PlanInfoProjection {
Integer getIsBasic(); // It works, but I have to convert Integer to Boolean to use.
//Boolean getIsBasic(); // doesn't work, but why???
//Boolean isBasic(); // also doesn't work
//boolean isBasic(); // also doesn't work
}
}
It seems like this doesn't work out of the box. What works for me (although I'm using DB2 so my datatype is different but this shouldn't be a problem) is to annotate it and use SpEL like this:
#Value("#{target.isBasic == 1}")
boolean getIsBasic();
This just takes your int value (0 for false, 1 for true) and creturns a boolean value. Should also work with Boolean but I didn't test it.
Another option is to use #Value("#{T(Boolean).valueOf(target.isBasic)}") but this only works for String values, so you would have to store 'true' or 'false' in your database. With T() you can import Static classes into Spring Expression Language, and then just call the valueOf method which returns a boolean (either Boolean or boolean)

How to debug composite entity with "Incorrect syntax near the keyword 'FROM'" exception?

I created a new composite entity based on two new entities. Those in turn are based on new views, which are based on new queries. The queries are based on a mix of standard tables and views and custom tables.
Similar composite entities were created in the past and work.
When exporting the composite entity with a data project, I'm getting the following exceptions:
Exception in AX-DIXFRuntime event log:
System.Exception: Incorrect syntax near the keyword 'FROM'.
at Microsoft.Dynamics.AX.Framework.Tools.DMF.ServiceProxy.DmfEntitySharedTypesProxy.DoWork[T](Func`1 work)
at Dynamics.AX.Application.DMFGenerateSSISPackage.`generateFileDataV2(DMFDefinitionGroupExecution _dmfDefinitionGroupExecution, String _defGroupName, DMFFileFormat _fileFormat, DMFDelimiter _rowDelimiter, DMFDelimiter _columnDelimiter, String _codePage, String _locale, NoYes _isFirstRowHeader, NoYes _unicode, String _source, String _textQualifier, DMFXMLStyle _style, String _rootElement, String _filePath, Map _entitySyncVersion, Int32 _previewCount, Boolean #_entitySyncVersion_IsDefaultSet, Boolean #_previewCount_IsDefaultSet) in xppSource://Source/ApplicationFoundation\AxClass_DMFGenerateSSISPackage.xpp:line 1419
Exception in AX-DIXFSSISRuntime event log:
SSISexceptionMessage System.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near the keyword 'FROM'.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable)
at Microsoft.Dynamics.AX.Framework.Tools.DMF.SSISHelper.DMFCompositeEntity.GetDatasetForXMlExport(String stagingString)
at Microsoft.Dynamics.AX.Framework.Tools.DMF.SSISHelper.DMFCompositeEntity.ExportCompositeEntityToXML()
at Microsoft.Dynamics.AX.Framework.Tools.DMF.SSISHelperService.Service.ServiceHelper.ExportCompositeEntityToXML(DMFCompositeEntity dmfCompEnt) ClientConnectionId:9a234a11-809d-4d88-828d-8981bfb4faa8 Error Number:156,State:1,Class:15
What I've tried so far:
refresh the entities and composite entity with en-us language setting
debug DMFGenerateSSISPackage.generateFileDataV2 and compare with the export of a working composite entity > no obvious incorrect differences found
remove line entity from the composite entity > same issue
export header/line entity directly > works without issue
Question
My question is if there is a way to find out what the SQL is that caused the Incorrect syntax near the keyword 'FROM' exception. If there is no way, I'm happy to hear suggestions how I can further narrow down this issue.
The issue is caused by the length of the label text of the composite entity and the length of the entity names. They must not exceed a limit of 99 characters.
Assume that you have two entities with names
VeryLongNameWithSixtyCharactersThatIdentifyTheFirstEntity123 (60 characters)
AnotherLongNameWithSeventyCharactersThatIdentifyTheSecondEntity1234567 (70 characters)
Also assume that the label text of your entity is the following
Label text with 30 characters1
If you navigate to workspace Data management and open the list of entities, find the composite entity named Label text with 31 characters1 and open "Child entities".
It will show 2 entries named
Label text with 30 characters1_VeryLongNameWithSixtyCharactersThatIdentifyTheFirstEntity123 (90 characters)
Label text with 30 characters1_AnotherLongNameWithSeventyCharactersThatIdentifyTheSecondEntity1234567 (100 characters)
This composite entity will export correctly.
But if you add another character to the name of the second entity, the second entry of the child entities will have 101 characters. This will cause the described exception error.
Fix by Microsoft
In issue 2086 of the Microsoft documentation, they announced to introduce a check during compile time for this in PU 36 which is currently under investigation. See KB4549600.

In JSON boolean type allow to pass int, instead of throwing error

Here,
isChecked and
isPrime both are the boolean type. If I am passing integer to both value, in my java code instead of throwing exception/error (code should expect either 'true' or 'false'), it is mapping with true value in my POJO class. I am assuming that it because of any number greater than 0 will take boolean true. To avoid this thing, any suggestions? I am using jax-rs for deserializing and serialize to java object.
#JsonProperty
private boolean isChecked;
(In setter method, it set with true value)

Passing SqlGeometry To Simple.Data Stored Procedure

I am trying to pass a SqlGeometry type to a stored procedure using Simple.Data and SQL Server 2008. The stored procedure definition looks like this:
CREATE PROCEDURE [dbo].[spUpdateDamLocation]
(
#DamID int,
#Shape geometry
)
The call I am using for Simple.Data looks like this:
var db = Simple.Data.Database.OpenConnection(dbConn);
db.spUpdateDamLocation(DamID: damLocation.DamID, Shape: damLocation.Shape);
Where dbConn is a connection string, damLocation.DamID is an integer and damLocation.Shape is a SqlGeometry object.
The error I am getting is:
System.ArgumentException: UdtTypeName property must be set for UDT parameters.
at System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc)
at System.Data.SqlClient.SqlCommand.SetUpRPCParameters(_SqlRPC rpc, Int32 startCount, Boolean inSchema, SqlParameterCollection parameters)
at System.Data.SqlClient.SqlCommand.BuildRPC(Boolean inSchema, SqlParameterCollection parameters, _SqlRPC& rpc)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
at Simple.Data.Ado.DbCommandExtensions.TryExecuteReader(IDbCommand command)
at Simple.Data.Ado.ProcedureExecutor.ExecuteReader(IDbCommand command)
at Simple.Data.Ado.ProcedureExecutor.Execute(IDictionary`2 suppliedParameters, IDbTransaction transaction)
at Simple.Data.Ado.ProcedureExecutor.Execute(IDictionary`2 suppliedParameters)
at Simple.Data.Ado.AdoAdapter.Execute(String functionName, IDictionary`2 parameters)
at Simple.Data.Database.ExecuteFunction(Object& result, ExecuteFunctionCommand command)
at Simple.Data.DataStrategy.TryInvokeFunction(String functionName, Func`1 getFunctionArguments, Object& result)
at Simple.Data.DataStrategy.TryInvokeMember(InvokeMemberBinder binder, Object[] args, Object& result)
at CallSite.Target(Closure , CallSite , Object , Int32 , SqlGeometry )
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3[T0,T1,T2](CallSite site, T0 arg0, T1 arg1, T2 arg2)
Is there a way to specify a specific UDT of the parameter in Simple.Data? If I were just using ADO.NET I would do something like this:
SqlParameter sqlParam = sqlCmd.Parameters.Add("#Shape", SqlDbType.UDT);
sqlParam.UdtTypeName = "geometry";
sqlParam.Value = myTypeOfSqlGeometry;
Simple.Data doesn't currently handle user-defined types at the moment. Issue 163 on github raised a similar question several months ago as encountering a UDT crashed the SqlSchemaProvider. The bug was fixed but it doesn't look like there has been any further development into supporting SqlGeometry, SqlGeography and the like.
A stored procedure, as your're trying would seem to be the best way to go, but as UDTs aren't explicitly supported, perhaps sending the SqlGeometry object as its WKT literal equivalent with a call to ToString() would work?
var db = Simple.Data.Database.OpenConnection(dbConn);
db.spUpdateDamLocation(DamID: damLocation.DamID, Shape: damLocation.Shape.ToString());
Also, With Simple.Data v1 just around the corner, I'd suggest opening a new issue for UDT support to be added in v1.1 so you don't need to go through such hoops in the future.

Entity Framework SQL Exception: The supplied value is not a valid instance of data type float

I have an application using the Entity Framework with a SQL Server 2008 (Express) database. I'm getting an intermittent error while doing an update to an entity in the database which indicates that 'the supplied value is not a valid instance of data type float'. However, as best I can tell, the values it's setting will always be floats. They're cast from integers, but even still will always yield floats. If the code did manage to create an invalid float somehow, I would have thought that .NET would complain about it before it even got to SQL Server.
I've included the full exception, code extracts, and schema below.
Is there anything I could be missing here - for example, could a single value be considered a float in .NET but not in SQL Server? Alternatively, is there any way I can programmatically log the precision and scale of a float so that I can diagnose what's going on if the problem comes up again?
I've added some additional logging to try to capture exactly what's going on here, but this is an intermittent problem and I can't reproduce it myself.
The error is:
System.Data.UpdateException: An error occurred while updating the entries. See the inner exception for details. --->
System.Data.SqlClient.SqlException: The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 4 ("#1"): The supplied value is not a valid instance of data type float. Check the source data for invalid values. An example of an invalid value is data of numeric type with scale greater than precision.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues)
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
--- End of inner exception stack trace ---
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache)
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Objects.ObjectContext.SaveChanges()
at MyApplication.ImageProcessing.ProcessImage(Image image) in C:\Code\ImageProcessing.cs:line 224
Here's the code that is being executed. (Note that the Image class is the entity class from Entity Framework.)
private static System.Random _randomLocation = new System.Random();
private void ProcessImage(Image image)
{
float x = _randomLocation.Next(668); // note: the System.Random.Next method always returns an int
float y = 0 - image.Height; // note: image.Height is an int and is always around 300-600 in value in this application
image.X = x;
image.Y = y;
_dataContext.SaveChanges();
}
The schema extract for the table that this is referring to is:
CREATE TABLE Image
(
ImageID uniqueidentifier NOT NULL PRIMARY KEY,
X float NOT NULL,
Y float NOT NULL
)
Also I should note that the EF model uses the data type Single for the X and Y columns.
I got this exact same error. It turns out I was dividing a float by zero. This didn't throw an exception in the code at the time I did the division; when I tried to save this value in the database I got the error.
Hope this is useful to some of you reading the question - Thanks John for raising it.
Well, you already mentioned that you are trying to assign int to float. Try to convert that to float by multiply by 1.0.
float x = _randomLocation.Next(668); // note: the System.Random.Next method always returns an int
float y = 0 - image.Height; // note: image.Height is an int and is always around 300-600 in value in this application