Dictionary<string, int> throwing exception when serializing with protobuf-net - unity3d

I am trying to make protobuf-net work with Unity. From the lot of research I've done the last days, it seems to be complicated to get both to work fine together. I have right now a problem I can't get around, when building using IL2CPP.
The serialization appears to sometimes fail for certain types, like Dictionary<string, int> or Dictionary<string, float> but works fine for Dictionary<string, string>. To make things clear, I'm using protobuf-net version 2.4.6 from nuget as it seems that v3 isn't supported at all from unity (unimplemented IL2CPP methods). The occurring error is:
ExecutionEngineException: Attempting to call method 'ProtoBuf.Serializers.MapDecorator`3[[System.Collections.Generic.Dictionary`2[[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]::.cctor' for which no ahead of time (AOT) code was generated.
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00000] in <00000000000000000000000000000000>:0
at System.Reflection.MonoCMethod.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <00000000000000000000000000000000>:0
at System.Reflection.MonoCMethod.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <00000000000000000000000000000000>:0
at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <00000000000000000000000000000000>:0
at ProtoBuf.Meta.ValueMember.BuildSerializer () [0x00000] in <00000000000000000000000000000000>:0
at ProtoBuf.Meta.ValueMember.get_Serializer () [0x00000] in <00000000000000000000000000000000>:0
at ProtoBuf.Meta.MetaType.BuildSerializer () [0x00000] in <00000000000000000000000000000000>:0
at ProtoBuf.Meta.MetaType.get_Serializer () [0x00000] in <00000000000000000000000000000000>:0
at ProtoBuf.Meta.RuntimeTypeModel.Serialize (System.Int32 key, System.Object value, ProtoBuf.ProtoWriter dest) [0x00000] in <00000000000000000000000000000000>:0
at ProtoBuf.Meta.TypeModel.SerializeCore (ProtoBuf.ProtoWriter writer, System.Object value) [0x00000] in <00000000000000000000000000000000>:0
at ProtoBuf.Meta.TypeModel.Serialize (System.IO.Stream dest, System.Object value, ProtoBuf.SerializationContext context) [0x00000] in <00000000000000000000000000000000>:0
at ProtoBuf.Meta.TypeModel.Serialize (System.IO.Stream dest, System.Object value) [0x00000] in <00000000000000000000000000000000>:0
at ProtoBuf.Serializer.Serialize[T] (System.IO.Stream destination, T instance) [0x00000] in <00000000000000000000000000000000>:0
at SerializationTests.SerializeObject[T] (T objectToSave) [0x00000] in <00000000000000000000000000000000>:0
at SerializationTests.AttemptSerializingData[T] (T dataToSerialize, Entry entry) [0x00000] in <00000000000000000000000000000000>:0
at Entry.OnGUI () [0x00000] in <00000000000000000000000000000000>:0
The class I'm trying to serialize on a side project to test looks like this:
using System.Collections.Generic;
using ProtoBuf;
[ProtoContract]
public class DataDictionnary<T, U>
{
[ProtoMember(1)] private readonly Dictionary<T, U> someDictionnary = new Dictionary<T, U>();
public DataDictionnary()
{
}
public void AddValue(T key, U value)
{
if (someDictionnary.ContainsKey(key)) return;
someDictionnary.Add(key, value);
}
public override string ToString()
{
string s = $"{GetType()}";
foreach (var key in someDictionnary.Keys)
{
s += $" ({key}, {someDictionnary[key]})";
}
return s;
}
}
Is there a reason I can serialize only certain types of Dictionaries with primitives, anything I could use to make it work ?
Edit: my link.xml file supposed to prevent code stripping
<linker>
<assembly fullname="Test.Serialization" preserve="all"/>
<assembly fullname="protobuf-net" preserve="all"/>
</linker>
SerializationTests.cs
using System.IO;
using ProtoBuf;
public static class SerializationTests
{
public static void AttemptSerializingData<T>(T dataToSerialize, bool displayProto, Entry entry)
{
if (displayProto)
entry.AddLog(Serializer.GetProto<T>());
entry.AddLog($"Serializing {dataToSerialize}");
var serializedObject = SerializeObject(dataToSerialize);
entry.AddLog($"Done ({serializedObject.Length})");
var deserializedObject = DeserializeObject<T>(serializedObject);
entry.AddLog($"Done! {deserializedObject}");
}
private static T DeserializeObject<T>(byte[] bytes)
{
T result;
using (var stream = new MemoryStream(bytes))
{
result = Serializer.Deserialize<T>(stream);
}
return result;
}
private static byte[] SerializeObject<T>(T objectToSave)
{
byte[] convertedObject;
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, objectToSave);
convertedObject = stream.ToArray();
}
return convertedObject;
}
}
The error is thrown when calling AttemptSerializingData from this GUI code:
using System.Collections.Generic;
using UnityEngine;
public class Entry : MonoBehaviour
{
private readonly List<string> logs = new List<string>();
private string a = "0", b = "5", c = "-2";
private bool displayProto;
private void OnGUI()
{
displayProto = GUILayout.Toggle(displayProto, "Display proto data");
a = GUILayout.TextField(a);
b = GUILayout.TextField(b);
c = GUILayout.TextField(c);
{
if (GUILayout.Button("Test int") && int.TryParse(a, out int _a) && int.TryParse(b, out int _b) && int.TryParse(c, out int _c))
{
logs.Clear();
var data = new DataDictionnary<string, int>();
data.AddValue("plop", _a);
data.AddValue("pop", _b);
data.AddValue("plp", _c);
SerializationTests.AttemptSerializingData(data, displayProto, this);
}
}
if (GUILayout.Button("Test string"))
{
logs.Clear();
var data = new DataDictionnary<string, string>();
data.AddValue("plop", a);
data.AddValue("pop", b);
data.AddValue("plp", c);
SerializationTests.AttemptSerializingData(data, displayProto, this);
}
{
if (GUILayout.Button("Test float") && float.TryParse(a, out float _a) && float.TryParse(b, out float _b) && float.TryParse(c, out float _c))
{
logs.Clear();
var data = new DataDictionnary<string, float>();
data.AddValue("plop", _a);
data.AddValue("pop", _b);
data.AddValue("plp", _c);
SerializationTests.AttemptSerializingData(data, displayProto, this);
}
if (GUILayout.Button("Test int int"))
{
logs.Clear();
var data = new DataDictionnary<int, int>();
data.AddValue(0, 5);
data.AddValue(4, 41);
data.AddValue(2, 8);
SerializationTests.AttemptSerializingData(data, displayProto, this);
}
if (GUILayout.Button("Test bool string"))
{
logs.Clear();
var data = new DataDictionnary<bool, string>();
data.AddValue(true, "ouyhgv");
data.AddValue(false, "hoipkip");
data.AddValue(false, "fguoii");
SerializationTests.AttemptSerializingData(data, displayProto, this);
}
}
foreach (var log in logs)
{
GUILayout.Label(log);
}
}
public void AddLog(string text)
{
logs.Add(text);
}
}

I found a solution here. Declaring all of my Dictionnaries with the attribute solves the problem.
[ProtoMap(DisableMap = true)]
[ProtoMember(1)]
private readonly Dictionary<string, string> _stringData;

Related

Trying to save a game, but gets stuck every time. output log is saying "bag missing???""

I'm trying to save a game, but each time I save, the game jams up. The screen just freezes. I can unfreeze it by pressing escape and the game just continues. However, the save doesn't register. When I go back to the start menu and select the tile where I tried to save, the game freezes completely, even though it seems empty. Anybody got any ideas what's going wrong?
7/05/2020 16:07:50 / Save[0] bag missing???
7/05/2020 16:09:09 / Save[0] Error during SaveInfos : Mono.Data.SqliteClient.SqliteSyntaxException: 43 values for 40 columns
at Mono.Data.SqliteClient.SqliteCommand.GetNextStatement (System.IntPtr pzStart, System.IntPtr& pzTail, System.IntPtr& pStmt) [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.SqliteClient.SqliteCommand.ExecuteReader (System.Data.CommandBehavior behavior, System.Boolean want_results, System.Int32& rows_affected) [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.SqliteClient.SqliteCommand.ExecuteNonQuery () [0x00000] in <00000000000000000000000000000000>:0
at DBManager.SaveInfos (CTEnum+SaveTableDataKind _kind, System.Int32 _num) [0x00000] in <00000000000000000000000000000000>:0
at DataMgr.SaveGameData () [0x00000] in <00000000000000000000000000000000>:0
at SaveNLoad.SaveSlot () [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.GUI+WindowFunction.Invoke (System.Int32 id) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.Events.InvokableCall`1[T1].Invoke (T1 args0) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <00000000000000000000000000000000>:0
at System.Reflection.EventInfo+AddEventAdapter.Invoke (System.Object _this, System.Delegate dele) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.StandaloneInputModule.ReleaseMouse (UnityEngine.EventSystems.PointerEventData pointerEvent, UnityEngine.GameObject currentOverGo) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.StandaloneInputModule.ProcessMousePress (UnityEngine.EventSystems.PointerInputModule+MouseButtonEventData data) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent (System.Int32 id) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.StandaloneInputModule.Process () [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.EventSystem.Update () [0x00000] in <00000000000000000000000000000000>:0
7/05/2020 16:09:28 / Save[1] Error during SaveInfos : Mono.Data.SqliteClient.SqliteSyntaxException: 43 values for 40 columns
at Mono.Data.SqliteClient.SqliteCommand.GetNextStatement (System.IntPtr pzStart, System.IntPtr& pzTail, System.IntPtr& pStmt) [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.SqliteClient.SqliteCommand.ExecuteReader (System.Data.CommandBehavior behavior, System.Boolean want_results, System.Int32& rows_affected) [0x00000] in <00000000000000000000000000000000>:0
at Mono.Data.SqliteClient.SqliteCommand.ExecuteNonQuery () [0x00000] in <00000000000000000000000000000000>:0
at DBManager.SaveInfos (CTEnum+SaveTableDataKind _kind, System.Int32 _num) [0x00000] in <00000000000000000000000000000000>:0
at DataMgr.SaveGameData () [0x00000] in <00000000000000000000000000000000>:0
at SaveNLoad.SaveSlot () [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.GUI+WindowFunction.Invoke (System.Int32 id) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.Events.InvokableCall`1[T1].Invoke (T1 args0) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <00000000000000000000000000000000>:0
at System.Reflection.EventInfo+AddEventAdapter.Invoke (System.Object _this, System.Delegate dele) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.StandaloneInputModule.ReleaseMouse (UnityEngine.EventSystems.PointerEventData pointerEvent, UnityEngine.GameObject currentOverGo) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.StandaloneInputModule.ProcessMousePress (UnityEngine.EventSystems.PointerInputModule+MouseButtonEventData data) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent (System.Int32 id) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.StandaloneInputModule.Process () [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.EventSystems.EventSystem.Update () [0x00000] in <00000000000000000000000000000000>:0
I'm not an expert on sql, but this error seams do describe that you are trying to save more values than you have variables for
7/05/2020 16:09:09 / Save[0] Error during SaveInfos : Mono.Data.SqliteClient.SqliteSyntaxException: 43 values for 40 columns

Asp.net core rc1, dbcontext connection is closed in IStringLocalizer GetString method

Asp.net core rc1, dbcontext connection is closed in IStringLocalizer GetString method. Happening only when VS2015 is on Debug mode and only once at start up.
I am using Autofac DI, but same issue (without autofac) using the buildin DI.
When I am running the App in debug mode and only at start up, producing the following error. When I refresh the browser all fine, no errors. If I run the App without debugging, no errors, everything runs normally.
Something's wrong with the debugging threat and the DI? Any ideas?
Error on browser:
A database operation failed while processing the request.
InvalidOperationException: ExecuteReader requires an open and
available Connection. The connection's current state is closed.
Output window:
Microsoft.Data.Entity.Storage.Internal.RelationalCommandBuilderFactory: Information: Executed DbCommand (55ms) [Parameters=[#___cultureName_0='?', #__name_1='?'], CommandType='Text', CommandTimeout='30']
SELECT TOP(1) [l].[CultureId], [l].[Name], [l].[Value]
FROM [UIResources] AS [l]
WHERE ([l].[CultureId] = #___cultureName_0) AND ([l].[Name] = #__name_1)
Microsoft.Data.Entity.Query.Internal.QueryCompiler: Error: An exception occurred in the database while iterating the results of a query.
System.NullReferenceException: Not Specified object reference to an instance object.
σε System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
σε System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
σε System.Data.SqlClient.SqlConnection.Open()
σε Microsoft.Data.Entity.Storage.RelationalConnection.Open()
σε Microsoft.Data.Entity.Query.Internal.QueryingEnumerable.Enumerator.MoveNext()
σε System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
σε System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
σε lambda_method(Closure , QueryContext )
σε Microsoft.Data.Entity.Query.Internal.QueryCompiler.<>c__DisplayClass18_1`1.<CompileQuery>b__1(QueryContext qc)
Microsoft.Data.Entity.Query.Internal.QueryCompiler: Error: An exception occurred in the database while iterating the results of a query.
System.InvalidOperationException: ExecuteReader requires an open and available Connection. The connection's current state is closed.
at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
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 Microsoft.Data.Entity.Storage.Internal.RelationalCommand.<>c__DisplayClass17_0.<ExecuteReader>b__0(DbCommand cmd, IRelationalConnection con)
at Microsoft.Data.Entity.Storage.Internal.RelationalCommand.Execute[T](IRelationalConnection connection, Func`3 action, String executeMethod, Boolean openConnection, Boolean closeConnection)
at Microsoft.Data.Entity.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, Boolean manageConnection)
at Microsoft.Data.Entity.Query.Internal.QueryingEnumerable.Enumerator.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at lambda_method(Closure , QueryContext )
at Microsoft.Data.Entity.Query.Internal.QueryCompiler.<>c__DisplayClass18_1`1.<CompileQuery>b__1(QueryContext qc)
Exception thrown: 'System.NullReferenceException' in EntityFramework.Core.dll
Exception thrown: 'System.InvalidOperationException' in EntityFramework.Core.dll
This is my startup:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc().AddViewLocalization();
services.AddMvc().AddDataAnnotationsLocalization();
services.AddLocalization();
// Create the Autofac container builder.
var builder = new ContainerBuilder();
// Populate the services from the collection.
// This have to come First.
builder.Populate(services);
// Register dependencies.
builder.RegisterType<AuthMessageSender>().As<IEmailSender>().InstancePerLifetimeScope();
builder.RegisterType<AuthMessageSender>().As<ISmsSender>().InstancePerLifetimeScope();
builder.RegisterType<DataInitializer>().As<IDataInitializer>().InstancePerLifetimeScope();
builder.RegisterType<CultureHelper>().As<ICultureHelper>().InstancePerLifetimeScope();
builder.RegisterType<RouteRequestCultureProvider>().InstancePerLifetimeScope();
builder.RegisterType<CultureActionFilter>().InstancePerLifetimeScope();
builder.RegisterType<DbStringLocalizerFactory>().As<IStringLocalizerFactory>().InstancePerLifetimeScope();
// DbStringLocalizer registers with InstancePerDependency,
// because localization requires a new instance of IStringLocalizer created in the IStringLocalizerFactory.
builder.RegisterType<DbStringLocalizer>().As<IStringLocalizer>().InstancePerDependency();
// Build the container.
var container = builder.Build();
// Return the IServiceProvider resolved from the container.
return container.Resolve<IServiceProvider>();
}
This is Localization implementation:
public class DbStringLocalizerFactory : IStringLocalizerFactory
{
private IServiceProvider _serviceProvider;
public DbStringLocalizerFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IStringLocalizer Create(Type resourceSource)
{
return _serviceProvider.GetService<IStringLocalizer>();
}
public IStringLocalizer Create(string baseName, string location)
{
return _serviceProvider.GetService<IStringLocalizer>();
}
}
public class DbStringLocalizer : IStringLocalizer
{
private ApplicationDbContext _db;
private string _cultureName;
public DbStringLocalizer(ApplicationDbContext db)
: this(db, CultureInfo.CurrentCulture)
{
}
public DbStringLocalizer(ApplicationDbContext db, CultureInfo cultureInfo)
{
_db = db;
_cultureName = cultureInfo.Name;
}
public LocalizedString this[string name]
{
get
{
var value = GetString(name);
return new LocalizedString(name, value ?? name, resourceNotFound: value == null);
}
}
public LocalizedString this[string name, params object[] arguments]
{
get
{
var format = GetString(name);
var value = string.Format(format ?? name, arguments);
return new LocalizedString(name, value, resourceNotFound: format == null);
}
}
private string GetString(string name)
{
//try
//{
var query = _db.UIResources.Where(l => l.CultureId == _cultureName);
var value = query.FirstOrDefault(l => l.Name == name);
return value?.Value;
//}
//catch
//{
// return null;
//}
}
public IEnumerable<LocalizedString> GetAllStrings(bool includeAncestorCultures)
{
return _db.UIResources.Where(l => l.CultureId == _cultureName)
.Select(l => new LocalizedString(l.Name, l.Value, true));
}
public IStringLocalizer WithCulture(CultureInfo culture)
{
return new DbStringLocalizer(_db, culture);
}
}
The IDataInitializer registration as scoped service in
builder.RegisterType<DataInitializer>().As<IDataInitializer>().InstancePerLifetimeScope();
seems odd, as a data initializer is expected to be called only once, when the application starts to ensure the database is created and filled with data required to run the application or after an update.
I suspect you dispose the scoped db context somewhere inside your DataInitializer class, so it becomes unavailable during your request because your IoC container will always return the same instance for the duration of the request.

Spatial DataReader and Wrapping Providers in EF6

To get my head around the new style of wrapping providers in EF6 I have put a quick sample together but I am struggling when it comes to the spatial data reader.
The exception I get is
Specified type is not registered on the target server.System.Data.Entity.Spatial.DbGeometry, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
Below is the code... if anyone could help me identify what is wrong it would be much appreciated.
Model
public class TestEF6DataSource : DbContext
{
public DbSet<MattShape> MattShapes { get; set; }
}
public class MattShape
{
[Key]
public int MattShapeId { get; set; }
[Required]
public DbGeometry GeoShape { get; set; }
}
Migrations
public sealed class Configuration : DbMigrationsConfiguration<TestEF6DataSource>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(TestEF6DataSource context)
{
context.MattShapes.AddOrUpdate(
m => m.MattShapeId,
new MattShape { MattShapeId = 1, GeoShape = DbGeometry.FromText("POLYGON ((1843503.54576196 5743170.10983084, 1843627.97736856 5743384.66544795, 1843557.59765677 5743393.36080548, 1843362.48753989 5743417.46230251, 1843361.11361057 5743417.63180584, 1843358.43835504 5743418.34609364, 1843355.88774656 5743419.42171531, 1843353.50983276 5743420.83971631, 1843352.42925232 5743421.70492403, 1843051.20263201 5743663.02873092, 1843050.40246141 5743663.67014246, 1843048.94101245 5743665.10920791, 1843047.63448048 5743666.69052689, 1843046.49589101 5743668.39810608, 1843045.53827419 5743670.21195005, 1843044.77165509 5743672.11506149, 1843044.20306302 5743674.085437, 1843043.83952263 5743676.10507526, 1843043.76129276 5743677.12752066, 1843043.68306289 5743678.14996605, 1843043.73770804 5743680.20110406, 1843044.00148376 5743682.23547495, 1843044.47141291 5743684.23206429, 1843045.14351779 5743686.16985646, 1843046.01081798 5743688.02883293, 1843047.06232975 5743689.78997102, 1843048.28907043 5743691.4342504, 1843048.98356169 5743692.18944876, 1843227.79751488 5743886.66320856, 1843370.49789926 5744041.86289133, 1843211.63121968 5744181.85544627, 1843210.88004919 5744182.51692323, 1843209.51761462 5744183.9841149, 1843208.30811202 5744185.57955102, 1843207.26456693 5744187.28723829, 1843206.3960028 5744189.09117878, 1843205.7124471 5744190.97237412, 1843205.219924 5744192.91282186, 1843204.92345948 5744194.89251733, 1843204.87426871 5744195.89198485, 1843204.82507793 5744196.89145237, 1843204.92780195 5744198.89162105, 1843205.22865675 5744200.87000785, 1843205.72666166 5744202.80960272, 1843206.41483744 5744204.68938653, 1843207.28720192 5744206.49134292, 1843208.33477247 5744208.1964515, 1843209.548563 5744209.78869344, 1843210.23107302 5744210.52086848, 1843362.82471731 5744374.04062576, 1843521.47199211 5744544.04810409, 1843522.80403726 5744545.4754015, 1843525.96805836 5744547.76127718, 1843529.51504843 5744549.39225262, 1843533.31000687 5744550.30713888, 1843537.21089892 5744550.47075254, 1843541.06965155 5744549.87791897, 1843544.74116062 5744548.55148175, 1843548.0862959 5744546.53930455, 1843549.53359801 5744545.22929443, 1844144.05575353 5744006.88500424, 1844169.18539025 5743983.5857433, 1844170.63172801 5743982.24570703, 1844172.94368956 5743979.05168963, 1844174.58874644 5743975.46769333, 1844175.50270343 5743971.63171704, 1844175.57703662 5743969.66175839, 1844175.90023907 5743961.04656371, 1844175.97457214 5743959.07660504, 1844175.5375125 5743956.34865246, 1844175.73760702 5743956.35989003, 1844177.73678424 5743956.27215751, 1844179.71618148 5743955.98629701, 1844181.65778673 5743955.50428874, 1844183.54258396 5743954.83111332, 1844185.34955492 5743953.97274958, 1844187.06267936 5743952.93918428, 1844188.66293657 5743951.73940016, 1844189.4001205 5743951.0628946, 1844199.50135086 5743941.78666567, 1844213.84039117 5743928.61827538, 1844215.28972002 5743927.28724656, 1844217.61466838 5743924.11025168, 1844219.27671508 5743920.54228211, 1844219.35211419 5743920.23420591, 1844219.64432342 5743920.18952037, 1844223.35289272 5743918.83709466, 1844226.72609487 5743916.78591001, 1844228.17943055 5743915.45088351, 1844242.51647028 5743902.28248667, 1844253.4640615 5743892.22881894, 1844254.21126251 5743891.54231917, 1844255.55975269 5743890.02607475, 1844256.74730665 5743888.38057548, 1844257.7628975 5743886.62381815, 1844258.59449784 5743884.7737984, 1844259.23508291 5743882.84851766, 1844259.67862504 5743880.86898012, 1844259.91909887 5743878.85418888, 1844259.93628859 5743877.83967025, 1844259.97595609 5743875.56550898, 1844263.40172796 5743875.62750567, 1844265.30771411 5743875.66172916, 1844269.06349335 5743875.01072919, 1844272.62898191 5743873.66213868, 1844275.87505338 5743871.66483413, 1844277.28130799 5743870.37777789, 1844293.26093854 5743855.74349582, 1844293.42794675 5743855.81372633, 1844297.16404668 5743856.59746499, 1844300.98202765 5743856.66191644, 1844304.74282077 5743856.00191699, 1844308.31032266 5743854.64332287, 1844311.55740795 5743852.63501293, 1844312.96166863 5743851.34195079, 1844366.48183378 5743802.05767893, 1844367.94418863 5743800.71065451, 1844370.28118872 5743797.49464845, 1844371.94128574 5743793.88164838, 1844372.85727827 5743790.01365209, 1844372.92562613 5743788.02667511, 1844372.99397396 5743786.03969812, 1844372.34618617 5743782.11786455, 1844370.93975308 5743778.39926161, 1844368.82953432 5743775.03003047, 1844367.46347793 5743773.58568301, 1844311.37120972 5743714.28931765, 1844598.56152946 5743510.53102903, 1844599.82925634 5743509.63101582, 1844602.05797441 5743507.46143768, 1844603.92386625 5743504.97427061, 1844605.3828408 5743502.22749453, 1844606.40080074 5743499.28910624, 1844606.95165187 5743496.22811234, 1844607.02330055 5743493.11953884, 1844606.61466136 5743490.03642345, 1844606.1741564 5743488.54511938, 1844558.82589522 5743328.15393844, 1844545.72733704 5743226.88587176, 1844545.50322096 5743225.15769254, 1844544.46552075 5743221.83172273, 1844542.86925421 5743218.73523003, 1844540.76133973 5743215.96031771, 1844539.4830261 5743214.77621074, 1844471.09777847 5743151.40250573, 1844439.20618072 5743078.48089337, 1844438.77908038 5743077.50588234, 1844437.72365546 5743075.65568148, 1844436.47798437 5743073.92932726, 1844435.05605492 5743072.34384485, 1844433.47485308 5743070.9192645, 1844431.75037123 5743069.6696121, 1844429.90260273 5743068.60991869, 1844427.95354434 5743067.75321654, 1844426.93937208 5743067.42987565, 1844347.35981 5743042.11069952, 1844087.70346261 5742812.08654871, 1844086.51504258 5742811.03362263, 1844083.8365753 5742809.32963639, 1844080.92346809 5742808.06961547, 1844077.84672431 5742807.28365755, 1844074.68536083 5742806.99386527, 1844071.51841542 5742807.20433173, 1844068.42393221 5742807.91314573, 1844065.47897565 5742809.10038539, 1844064.11929846 5742809.91825389, 1843510.54101528 5743142.92357374, 1843508.86995706 5743143.92917723, 1843505.97737608 5743146.54822255, 1843503.64650513 5743149.67618338, 1843501.9625264 5743153.19509576, 1843500.99062767 5743156.97296537, 1843500.76599237 5743160.86775796, 1843501.29879528 5743164.7334084, 1843502.56719526 5743168.42281405, 1843503.54576196 5743170.10983084))") },
new MattShape { MattShapeId = 2, GeoShape = DbGeometry.FromText("POLYGON ((1767189.79377487 5904558.30070561, 1767215.1492355 5904492.43152391, 1767215.22475214 5904445.62448443, 1767192.95192382 5904443.13290794, 1767196.09833442 5904422.95242129, 1767174.81164464 5904414.75687878, 1767129.42429366 5904534.9388636, 1767189.79377487 5904558.30070561))") }
);
context.SaveChanges();
}
}
Wrappers
public class TestDbProviderServices : DbProviderServices
{
private DbProviderServices InnerProviderServices { get; set; }
public TestDbProviderServices(DbProviderServices inner)
{
InnerProviderServices = inner;
}
protected override DbCommandDefinition CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
{
return InnerProviderServices.CreateCommandDefinition(providerManifest, commandTree);
}
protected override string GetDbProviderManifestToken(DbConnection connection)
{
return InnerProviderServices.GetProviderManifestToken(connection);
}
protected override DbProviderManifest GetDbProviderManifest(string manifestToken)
{
return InnerProviderServices.GetProviderManifest(manifestToken);
}
protected override DbSpatialDataReader GetDbSpatialDataReader(DbDataReader fromReader, string manifestToken)
{
return InnerProviderServices.GetSpatialDataReader(fromReader, manifestToken);
}
}
public class TestDbConnectionFactory : IDbConnectionFactory
{
private IDbConnectionFactory InnerDbConnectionFactory { get; set; }
public TestDbConnectionFactory(IDbConnectionFactory inner)
{
InnerDbConnectionFactory = inner;
}
public DbConnection CreateConnection(string nameOrConnectionString)
{
return InnerDbConnectionFactory.CreateConnection(nameOrConnectionString);
}
}
Test Console App
class Program
{
static void Main(string[] args)
{
DbConfiguration.Loaded += (_, a) =>
{
a.ReplaceService<DbProviderServices>((s, k) => new TestDbProviderServices(s));
a.ReplaceService<IDbConnectionFactory>((s, k) => new TestDbConnectionFactory(s));
};
var db = new TestEF6DataSource();
var point = CreatePoint(1843503.54576196, 5743170.10983084);
var shapes = db.MattShapes.Where(s => s.GeoShape.Intersects(point)).Select(s => s.MattShapeId).ToList();
foreach (var shape in shapes)
{
System.Console.WriteLine(shape);
}
System.Console.ReadKey();
}
private static DbGeometry CreatePoint(double x, double y)
{
var text = string.Format(CultureInfo.InvariantCulture.NumberFormat, "POINT({0} {1})", x, y);
return DbGeometry.PointFromText(text, 0);
}
}
I am using EF 6.0.1 via NuGet. I must be missing something fairly obvious but not sure what it is!
Update
Stack trace
System.Data.Entity.Core.EntityCommandExecutionException was unhandled
HResult=-2146232004
Message=An error occurred while executing the command definition. See the inner exception for details.
Source=EntityFramework
StackTrace:
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
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.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.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 EFWrapper.Console.Program.Main(String[] args) in c:\Projects\EFWrapper\EFWrapper.Console\Program.cs:line 28
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.ArgumentException
HResult=-2147024809
Message=Specified type is not registered on the target server.System.Data.Entity.Spatial.DbGeometry, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089.
Source=System.Data
StackTrace:
at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, Boolean isCommandProc, Boolean sync, TaskCompletionSource`1 completion, Int32 startRpc, Int32 startParam)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
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.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<>c__DisplayClassb.<Reader>b__8()
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TInterceptionContext,TResult](Func`1 operation, TInterceptionContext interceptionContext, Action`1 executing, Action`1 executed)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
InnerException:
Update 2
I have created a sample app on Skydrive that you can download and see the issue I am getting
https://skydrive.live.com/redir?resid=8062EC63AFF4490A!107
Update 3
The hack required to make the provider wrapper work is as follows
protected override void SetDbParameterValue(DbParameter parameter, System.Data.Entity.Core.Metadata.Edm.TypeUsage parameterType, object value)
{
/*
* Hack
*
* SetParameterValue is internal and am unable to call it on the InnerProviderServices from here. This breaks the provider wrapper when making
* spatial queries in EF 6.0.1
* http://stackoverflow.com/questions/19966106/spatial-datareader-and-wrapping-providers-in-ef6
*/
if (InnerProviderServices == null)
throw new NullReferenceException("InnerProviderServices must not be NULL");
var setParameterValueMethod = InnerProviderServices.GetType().GetMethod("SetParameterValue", BindingFlags.NonPublic | BindingFlags.Instance);
setParameterValueMethod.Invoke(InnerProviderServices, new[] { parameter, parameterType, value });
}
It seems like a bug in the provider model. SqlProviderServices converts EDM spatial types to SqlServer spatial types in the SetParameterValue method however there is no public way to call this method from your wrapping provider. I created a bug for tracking this: https://entityframework.codeplex.com/workitem/1867. An ugly workaround would be to call the internal SetParameterValue method using reflection.

EntityFramework 6.0.0-alpha3 - EdmxWriter.WriteEdmx() fails after update to alpha3 from alpha2

The following extension works for EF6 alpha2 but stopped working with alpha3 with null reference exception. The failing statement is the EdmxWriter.WriteEdmx(..)
The views pre-generation is performed on a code-first context.
How to achieve pre-generate views using EF6 alpha3?
public static PreGeneratedViews PreGenerateViews<T>(this T dbContext) where T : DbContext
{
Trace.TraceInformation("PreGenerating views");
//define ef collections
EdmItemCollection edmItemCollection = null;
StoreItemCollection storeItemCollection = null;
StorageMappingItemCollection mappingItemCollection = null;
//get ef collections
GetItemCollections(
GetEdmx(dbContext),
out edmItemCollection,
out storeItemCollection,
out mappingItemCollection);
IList<EdmSchemaError> errors = null;
//get the generated views
Dictionary<string, string> extentViews = GetExtentViews(mappingItemCollection, out errors);
//return the pregenerated views as string (xml document)
return new PreGeneratedViews
{
EdmEntityContainerName = edmItemCollection.GetItems<EntityContainer>().Single().Name,
StoreEntityContainerName = storeItemCollection.GetItems<EntityContainer>().Single().Name,
HashOverMappingClosure =
ReflectionHelper.GetMappingClosureHash(edmItemCollection.EdmVersion,
mappingItemCollection),
HashOverAllExtentViews =
ReflectionHelper.GenerateHashForAllExtentViewsContent(edmItemCollection.EdmVersion,
extentViews),
ViewCount = extentViews.Count,
Views = CreateViews(extentViews),
ViewsEmbeddedResourceName =
string.Format("DbContextViews{0}.xml", Guid.NewGuid().ToString("N")),
};
}
private static XDocument GetEdmx(DbContext dbContext)
{
var ms = new MemoryStream();
using (XmlWriter writer = XmlWriter.Create(ms))
{
EdmxWriter.WriteEdmx(dbContext, writer);
}
ms.Position = 0;
return XDocument.Load(ms);
}
private static void SplitEdmx(XDocument edmx, out XmlReader csdlReader, out XmlReader ssdlReader,
out XmlReader mslReader)
{
// xml namespace agnostic to make it work with any version of Entity Framework
XNamespace edmxNs = edmx.Root.Name.Namespace;
XElement storageModels = edmx.Descendants(edmxNs + "StorageModels").Single();
XElement conceptualModels = edmx.Descendants(edmxNs + "ConceptualModels").Single();
XElement mappings = edmx.Descendants(edmxNs + "Mappings").Single();
ssdlReader = storageModels.Elements().Single(e => e.Name.LocalName == "Schema").CreateReader();
csdlReader = conceptualModels.Elements().Single(e => e.Name.LocalName == "Schema").CreateReader();
mslReader = mappings.Elements().Single(e => e.Name.LocalName == "Mapping").CreateReader();
}
private static void GetItemCollections(XDocument edmx, out EdmItemCollection edmItemCollection,
out StoreItemCollection storeItemCollection,
out StorageMappingItemCollection mappingItemCollection)
{
// extract csdl, ssdl and msl artifacts from the Edmx
XmlReader csdlReader, ssdlReader, mslReader;
SplitEdmx(edmx, out csdlReader, out ssdlReader, out mslReader);
// Initialize item collections
edmItemCollection = new EdmItemCollection(new[] {csdlReader});
storeItemCollection = new StoreItemCollection(new[] {ssdlReader});
mappingItemCollection = new StorageMappingItemCollection(edmItemCollection, storeItemCollection,
new[] {mslReader});
}
private static Dictionary<string, string> GetExtentViews(StorageMappingItemCollection mappingItemCollection,
out IList<EdmSchemaError> errors)
{
Dictionary<EntitySetBase, string> views = ReflectionHelper.GenerateViews(mappingItemCollection, out errors);
if (errors != null && errors.Any())
{
return null;
}
var extentViews = new Dictionary<string, string>(views.Count);
foreach (var kvp in views)
{
extentViews.Add(
GetExtentFullName(kvp.Key),
kvp.Value.Replace("\r\n", "\n")); // replace accounts for Xml new line normalization
}
return extentViews;
}
private static string GetExtentFullName(EntitySetBase entitySet)
{
return string.Format("{0}.{1}", entitySet.EntityContainer.Name, entitySet.Name);
}
private static string CreateViews(Dictionary<string, string> extentViews)
{
var sb = new StringBuilder();
//var embeddedViewsFileName = Path.ChangeExtension(Host.TemplateFile, "xml");
using (XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings
{
Indent = true,
Encoding = Encoding.UTF8
}))
{
writer.WriteStartElement("views");
foreach (var kvp in extentViews)
{
writer.WriteStartElement("view");
writer.WriteAttributeString("extent", kvp.Key);
writer.WriteCData(kvp.Value);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
return sb.ToString();
}
#region Nested type: ReflectionHelper
private static class ReflectionHelper
{
private static readonly Assembly efAssembly = typeof (StorageMappingItemCollection).Assembly;
private static readonly MethodInfo generateViewsMethodInfo =
typeof (StorageMappingItemCollection).GetMethod("GenerateEntitySetViews",
BindingFlags.NonPublic | BindingFlags.Instance);
private static readonly MethodInfo getMappingClosureHashMethodInfo =
efAssembly.GetType("System.Data.Entity.Core.Mapping.MetadataMappingHasherVisitor", true)
.GetMethod("GetMappingClosureHash", BindingFlags.Static | BindingFlags.NonPublic);
private static readonly MethodInfo generateHashForAllExtentViewsContentMethodInfo =
efAssembly.GetType("System.Data.Entity.Core.Common.Utils.MetadataHelper", true)
.GetMethod("GenerateHashForAllExtentViewsContent", BindingFlags.Static | BindingFlags.NonPublic);
public static Dictionary<EntitySetBase, string> GenerateViews(
StorageMappingItemCollection mappingItemCollection, out IList<EdmSchemaError> errors)
{
errors = null;
return
(Dictionary<EntitySetBase, string>)
generateViewsMethodInfo.Invoke(mappingItemCollection, new object[] {errors});
}
public static string GetMappingClosureHash(double schemaVersion,
StorageMappingItemCollection mappingItemCollection)
{
return (string) getMappingClosureHashMethodInfo.Invoke(
null,
new object[]
{
schemaVersion,
// CodeFirst currently creates always one entity container
mappingItemCollection.GetItems<GlobalItem>().Single(
i => i.GetType().Name == "StorageEntityContainerMapping")
});
}
public static string GenerateHashForAllExtentViewsContent(double schemaVersion,
Dictionary<string, string> extentViews)
{
return (string) generateHashForAllExtentViewsContentMethodInfo.Invoke(
null,
new object[] {schemaVersion, extentViews});
}
}
The stacktrace is the following:
NullReferenceException
at: System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.VisitEdmAssociationSet(AssociationSet item)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitCollection[T](IEnumerable1 collection, Action1 visitMethod)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitAssociationSets(EntityContainer container, IEnumerable`1 associationSets)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitEdmEntityContainer(EntityContainer item)
at: System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.VisitEdmEntityContainer(EntityContainer item)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitCollection[T](IEnumerable1 collection, Action1 visitMethod)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitEntityContainers(IEnumerable`1 entityContainers)
at: System.Data.Entity.Edm.EdmModelVisitor.VisitEdmModel(EdmModel item)
at: System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.Visit(EdmModel edmModel, String namespaceName, String provider, String providerManifestToken)
at: System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.Visit(EdmModel edmModel, String provider, String providerManifestToken)
at: System.Data.Entity.Edm.Serialization.SsdlSerializer.Serialize(EdmModel dbDatabase, String provider, String providerManifestToken, XmlWriter xmlWriter, Boolean serializeDefaultNullability)
at: System.Data.Entity.ModelConfiguration.Edm.Serialization.EdmxSerializer.WriteEdmxRuntime()
at: System.Data.Entity.ModelConfiguration.Edm.Serialization.EdmxSerializer.Serialize(DbDatabaseMapping databaseMapping, DbProviderInfo providerInfo, XmlWriter xmlWriter)
at: System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbModel model, XmlWriter writer)
at: System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer)
at: **.DbContextPreGenerateViewExtension.GetEdmx(DbContext dbContext)
Thanks!
I just submitted a fix for work item 867 (35852e8392ad). It should fix the NRE. The fix should be included in the today's nightly build. Can you give it a try and let me know if this fixed the problem?
This is a known bug in Alpha 3.

XmlSerializer and XmlException - Root element is missing

Why doesn't the following deserialize? The exception is shown below. Note that I'm using new streams serialization and deserialization to avoid "end of stream" errors. I'm also using new XmlSerializer instances to avoid similar problems there.
Serialization works fine. I've reviewed MANY of the similarly-named questions to no avail.
Exception:
System.InvalidOperationException was unhandled
Message=There is an error in XML document (0, 0).
Source=System.Xml
StackTrace:
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
at TestSerilalization.Program.Main(String[] args) in D:\MyDocs\Projects\dsb\Src\Apps\RecipeMgr\Other\TestSerlialization\Program.cs:line 45
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Xml.XmlException
Message=Root element is missing.
Source=System.Xml
LineNumber=0
LinePosition=0
SourceUri=""
StackTrace:
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlTextReader.Read()
at System.Xml.XmlReader.MoveToContent()
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderClass1.Read4_Class1()
InnerException:
Code:
static void Main(string[] args)
{
XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer( typeof( Class1 ), "http://xxx" );
Class1 c1 = new Class1();
FileStream strm = File.Create( "d:\\temp\\classes.xml" );
xmlSerializer.Serialize( strm, c1 );
strm.Close();
Class1 c2 = null;
FileStream strm2 = File.Create( "d:\\temp\\classes.xml" );
XmlSerializer xmlSerializer2 = new System.Xml.Serialization.XmlSerializer( typeof( Class1 ), "http://xxx" );
c2 = (Class1)xmlSerializer2.Deserialize( strm2 );
strm2.Close();
}
public class Class1
{
public Class1()
{
m_Class2 = new Class2();
}
public Class2 class2
{
get { return m_Class2; }
set { m_Class2 = value; }
}
private Class2 m_Class2;
}
public class Class2
{
public Class2()
{
m_Int = 999;
m_Str = "sdfsdfsdsd";
}
public int getInt
{
get { return m_Int; }
set { m_Int = value; }
}
public string getStr
{
get { return m_Str; }
set { m_Str = value; }
}
private int m_Int;
private string m_Str;
}
The generated xml:
<?xml version="1.0"?>
<Class1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://xxx">
<class2>
<getInt>999</getInt>
<getStr>sdfsdfsdsd</getStr>
</class2>
</Class1>
File.Create creates a new blank file.
Therefore, you're reading an empty file.
You probably want File.Open.