diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/Department.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/Department.cs
new file mode 100644
index 00000000..974533a2
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/Department.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Data.Linq;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+ [MetadataType(typeof(DepartmentMetadata))]
+ public partial class Department
+ {
+ [JsonConverter(typeof(DepartmentConverter))]
+ public class DepartmentMetadata
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/DepartmentConverter.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/DepartmentConverter.cs
new file mode 100644
index 00000000..9187cbd8
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/DepartmentConverter.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+ public class DepartmentConverter : JsonConverter
+ {
+ public override void WriteJson(JsonWriter writer, object value)
+ {
+ Department department = (Department)value;
+
+ JObject o = new JObject();
+ o["DepartmentId"] = new JValue(department.DepartmentId.ToString());
+ o["Name"] = new JValue(new string(department.Name.Reverse().ToArray()));
+
+ o.WriteTo(writer);
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType)
+ {
+ JObject o = JObject.Load(reader);
+
+ Department department = new Department();
+ department.DepartmentId = new Guid((string)o["DepartmentId"]);
+ department.Name = new string(((string) o["Name"]).Reverse().ToArray());
+
+ return department;
+ }
+
+ public override bool CanConvert(Type objectType)
+ {
+ return (objectType == typeof (Department));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/GuidByteArrayConverter.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/GuidByteArrayConverter.cs
new file mode 100644
index 00000000..79fa74bc
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/GuidByteArrayConverter.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+ public class GuidByteArrayConverter : JsonConverter
+ {
+ public override void WriteJson(JsonWriter writer, object value)
+ {
+ Guid guid = (Guid) value;
+ writer.WriteValue(Convert.ToBase64String(guid.ToByteArray()));
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType)
+ {
+ string encodedData = (string) reader.Value;
+ byte[] data = Convert.FromBase64String(encodedData);
+ return new Guid(data);
+ }
+
+ public override bool CanConvert(Type objectType)
+ {
+ return (objectType == typeof (Guid));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml
new file mode 100644
index 00000000..f1d089fd
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout
new file mode 100644
index 00000000..8f631b12
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.designer.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.designer.cs
new file mode 100644
index 00000000..4c978ca0
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.designer.cs
@@ -0,0 +1,726 @@
+#pragma warning disable 1591
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3074
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+ using System.Data.Linq;
+ using System.Data.Linq.Mapping;
+ using System.Data;
+ using System.Collections.Generic;
+ using System.Reflection;
+ using System.Linq;
+ using System.Linq.Expressions;
+ using System.ComponentModel;
+ using System;
+
+
+ public partial class LinqToSqlClassesDataContext : System.Data.Linq.DataContext
+ {
+
+ private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
+
+ #region Extensibility Method Definitions
+ partial void OnCreated();
+ partial void InsertPerson(Person instance);
+ partial void UpdatePerson(Person instance);
+ partial void DeletePerson(Person instance);
+ partial void InsertRole(Role instance);
+ partial void UpdateRole(Role instance);
+ partial void DeleteRole(Role instance);
+ partial void InsertPersonRole(PersonRole instance);
+ partial void UpdatePersonRole(PersonRole instance);
+ partial void DeletePersonRole(PersonRole instance);
+ partial void InsertDepartment(Department instance);
+ partial void UpdateDepartment(Department instance);
+ partial void DeleteDepartment(Department instance);
+ #endregion
+
+ public LinqToSqlClassesDataContext(string connection) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public LinqToSqlClassesDataContext(System.Data.IDbConnection connection) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public LinqToSqlClassesDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public LinqToSqlClassesDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public System.Data.Linq.Table Persons
+ {
+ get
+ {
+ return this.GetTable();
+ }
+ }
+
+ public System.Data.Linq.Table Roles
+ {
+ get
+ {
+ return this.GetTable();
+ }
+ }
+
+ public System.Data.Linq.Table PersonRoles
+ {
+ get
+ {
+ return this.GetTable();
+ }
+ }
+
+ public System.Data.Linq.Table Departments
+ {
+ get
+ {
+ return this.GetTable();
+ }
+ }
+ }
+
+ [Table(Name="")]
+ public partial class Person : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+
+ private string _FirstName;
+
+ private string _LastName;
+
+ private System.Guid _PersonId;
+
+ private System.Guid _DepartmentId;
+
+ private EntitySet _PersonRoles;
+
+ private EntityRef _Department;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnFirstNameChanging(string value);
+ partial void OnFirstNameChanged();
+ partial void OnLastNameChanging(string value);
+ partial void OnLastNameChanged();
+ partial void OnPersonIdChanging(System.Guid value);
+ partial void OnPersonIdChanged();
+ partial void OnDepartmentIdChanging(System.Guid value);
+ partial void OnDepartmentIdChanged();
+ #endregion
+
+ public Person()
+ {
+ this._PersonRoles = new EntitySet(new Action(this.attach_PersonRoles), new Action(this.detach_PersonRoles));
+ this._Department = default(EntityRef);
+ OnCreated();
+ }
+
+ [Column(Storage="_FirstName", CanBeNull=false)]
+ public string FirstName
+ {
+ get
+ {
+ return this._FirstName;
+ }
+ set
+ {
+ if ((this._FirstName != value))
+ {
+ this.OnFirstNameChanging(value);
+ this.SendPropertyChanging();
+ this._FirstName = value;
+ this.SendPropertyChanged("FirstName");
+ this.OnFirstNameChanged();
+ }
+ }
+ }
+
+ [Column(Storage="_LastName", CanBeNull=false)]
+ public string LastName
+ {
+ get
+ {
+ return this._LastName;
+ }
+ set
+ {
+ if ((this._LastName != value))
+ {
+ this.OnLastNameChanging(value);
+ this.SendPropertyChanging();
+ this._LastName = value;
+ this.SendPropertyChanged("LastName");
+ this.OnLastNameChanged();
+ }
+ }
+ }
+
+ [Column(Storage="_PersonId", IsPrimaryKey=true)]
+ public System.Guid PersonId
+ {
+ get
+ {
+ return this._PersonId;
+ }
+ set
+ {
+ if ((this._PersonId != value))
+ {
+ this.OnPersonIdChanging(value);
+ this.SendPropertyChanging();
+ this._PersonId = value;
+ this.SendPropertyChanged("PersonId");
+ this.OnPersonIdChanged();
+ }
+ }
+ }
+
+ [Column(Storage="_DepartmentId")]
+ public System.Guid DepartmentId
+ {
+ get
+ {
+ return this._DepartmentId;
+ }
+ set
+ {
+ if ((this._DepartmentId != value))
+ {
+ if (this._Department.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnDepartmentIdChanging(value);
+ this.SendPropertyChanging();
+ this._DepartmentId = value;
+ this.SendPropertyChanged("DepartmentId");
+ this.OnDepartmentIdChanged();
+ }
+ }
+ }
+
+ [Association(Name="Person_PersonRole", Storage="_PersonRoles", ThisKey="PersonId", OtherKey="PersonId")]
+ public EntitySet PersonRoles
+ {
+ get
+ {
+ return this._PersonRoles;
+ }
+ set
+ {
+ this._PersonRoles.Assign(value);
+ }
+ }
+
+ [Association(Name="Department_Person", Storage="_Department", ThisKey="DepartmentId", OtherKey="DepartmentId", IsForeignKey=true)]
+ public Department Department
+ {
+ get
+ {
+ return this._Department.Entity;
+ }
+ set
+ {
+ Department previousValue = this._Department.Entity;
+ if (((previousValue != value)
+ || (this._Department.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._Department.Entity = null;
+ previousValue.Persons.Remove(this);
+ }
+ this._Department.Entity = value;
+ if ((value != null))
+ {
+ value.Persons.Add(this);
+ this._DepartmentId = value.DepartmentId;
+ }
+ else
+ {
+ this._DepartmentId = default(System.Guid);
+ }
+ this.SendPropertyChanged("Department");
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ private void attach_PersonRoles(PersonRole entity)
+ {
+ this.SendPropertyChanging();
+ entity.Person = this;
+ }
+
+ private void detach_PersonRoles(PersonRole entity)
+ {
+ this.SendPropertyChanging();
+ entity.Person = null;
+ }
+ }
+
+ [Table(Name="")]
+ public partial class Role : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+
+ private string _Name;
+
+ private System.Guid _RoleId;
+
+ private EntitySet _PersonRoles;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnNameChanging(string value);
+ partial void OnNameChanged();
+ partial void OnRoleIdChanging(System.Guid value);
+ partial void OnRoleIdChanged();
+ #endregion
+
+ public Role()
+ {
+ this._PersonRoles = new EntitySet(new Action(this.attach_PersonRoles), new Action(this.detach_PersonRoles));
+ OnCreated();
+ }
+
+ [Column(Storage="_Name", CanBeNull=false)]
+ public string Name
+ {
+ get
+ {
+ return this._Name;
+ }
+ set
+ {
+ if ((this._Name != value))
+ {
+ this.OnNameChanging(value);
+ this.SendPropertyChanging();
+ this._Name = value;
+ this.SendPropertyChanged("Name");
+ this.OnNameChanged();
+ }
+ }
+ }
+
+ [Column(Storage="_RoleId", IsPrimaryKey=true)]
+ public System.Guid RoleId
+ {
+ get
+ {
+ return this._RoleId;
+ }
+ set
+ {
+ if ((this._RoleId != value))
+ {
+ this.OnRoleIdChanging(value);
+ this.SendPropertyChanging();
+ this._RoleId = value;
+ this.SendPropertyChanged("RoleId");
+ this.OnRoleIdChanged();
+ }
+ }
+ }
+
+ [Association(Name="Role_PersonRole", Storage="_PersonRoles", ThisKey="RoleId", OtherKey="RoleId")]
+ public EntitySet PersonRoles
+ {
+ get
+ {
+ return this._PersonRoles;
+ }
+ set
+ {
+ this._PersonRoles.Assign(value);
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ private void attach_PersonRoles(PersonRole entity)
+ {
+ this.SendPropertyChanging();
+ entity.Role = this;
+ }
+
+ private void detach_PersonRoles(PersonRole entity)
+ {
+ this.SendPropertyChanging();
+ entity.Role = null;
+ }
+ }
+
+ [Table(Name="")]
+ public partial class PersonRole : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+
+ private System.Guid _PersonId;
+
+ private System.Guid _RoleId;
+
+ private System.Guid _PersonRoleId;
+
+ private EntityRef _Person;
+
+ private EntityRef _Role;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnPersonIdChanging(System.Guid value);
+ partial void OnPersonIdChanged();
+ partial void OnRoleIdChanging(System.Guid value);
+ partial void OnRoleIdChanged();
+ partial void OnPersonRoleIdChanging(System.Guid value);
+ partial void OnPersonRoleIdChanged();
+ #endregion
+
+ public PersonRole()
+ {
+ this._Person = default(EntityRef);
+ this._Role = default(EntityRef);
+ OnCreated();
+ }
+
+ [Column(Storage="_PersonId")]
+ public System.Guid PersonId
+ {
+ get
+ {
+ return this._PersonId;
+ }
+ set
+ {
+ if ((this._PersonId != value))
+ {
+ if (this._Person.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnPersonIdChanging(value);
+ this.SendPropertyChanging();
+ this._PersonId = value;
+ this.SendPropertyChanged("PersonId");
+ this.OnPersonIdChanged();
+ }
+ }
+ }
+
+ [Column(Storage="_RoleId")]
+ public System.Guid RoleId
+ {
+ get
+ {
+ return this._RoleId;
+ }
+ set
+ {
+ if ((this._RoleId != value))
+ {
+ if (this._Role.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnRoleIdChanging(value);
+ this.SendPropertyChanging();
+ this._RoleId = value;
+ this.SendPropertyChanged("RoleId");
+ this.OnRoleIdChanged();
+ }
+ }
+ }
+
+ [Column(Storage="_PersonRoleId", IsPrimaryKey=true)]
+ public System.Guid PersonRoleId
+ {
+ get
+ {
+ return this._PersonRoleId;
+ }
+ set
+ {
+ if ((this._PersonRoleId != value))
+ {
+ this.OnPersonRoleIdChanging(value);
+ this.SendPropertyChanging();
+ this._PersonRoleId = value;
+ this.SendPropertyChanged("PersonRoleId");
+ this.OnPersonRoleIdChanged();
+ }
+ }
+ }
+
+ [Association(Name="Person_PersonRole", Storage="_Person", ThisKey="PersonId", OtherKey="PersonId", IsForeignKey=true)]
+ public Person Person
+ {
+ get
+ {
+ return this._Person.Entity;
+ }
+ set
+ {
+ Person previousValue = this._Person.Entity;
+ if (((previousValue != value)
+ || (this._Person.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._Person.Entity = null;
+ previousValue.PersonRoles.Remove(this);
+ }
+ this._Person.Entity = value;
+ if ((value != null))
+ {
+ value.PersonRoles.Add(this);
+ this._PersonId = value.PersonId;
+ }
+ else
+ {
+ this._PersonId = default(System.Guid);
+ }
+ this.SendPropertyChanged("Person");
+ }
+ }
+ }
+
+ [Association(Name="Role_PersonRole", Storage="_Role", ThisKey="RoleId", OtherKey="RoleId", IsForeignKey=true)]
+ public Role Role
+ {
+ get
+ {
+ return this._Role.Entity;
+ }
+ set
+ {
+ Role previousValue = this._Role.Entity;
+ if (((previousValue != value)
+ || (this._Role.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._Role.Entity = null;
+ previousValue.PersonRoles.Remove(this);
+ }
+ this._Role.Entity = value;
+ if ((value != null))
+ {
+ value.PersonRoles.Add(this);
+ this._RoleId = value.RoleId;
+ }
+ else
+ {
+ this._RoleId = default(System.Guid);
+ }
+ this.SendPropertyChanged("Role");
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+
+ [Table(Name="")]
+ public partial class Department : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+
+ private System.Guid _DepartmentId;
+
+ private string _Name;
+
+ private EntitySet _Persons;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnDepartmentIdChanging(System.Guid value);
+ partial void OnDepartmentIdChanged();
+ partial void OnNameChanging(string value);
+ partial void OnNameChanged();
+ #endregion
+
+ public Department()
+ {
+ this._Persons = new EntitySet(new Action(this.attach_Persons), new Action(this.detach_Persons));
+ OnCreated();
+ }
+
+ [Column(Storage="_DepartmentId", IsPrimaryKey=true)]
+ public System.Guid DepartmentId
+ {
+ get
+ {
+ return this._DepartmentId;
+ }
+ set
+ {
+ if ((this._DepartmentId != value))
+ {
+ this.OnDepartmentIdChanging(value);
+ this.SendPropertyChanging();
+ this._DepartmentId = value;
+ this.SendPropertyChanged("DepartmentId");
+ this.OnDepartmentIdChanged();
+ }
+ }
+ }
+
+ [Column(Storage="_Name", CanBeNull=false)]
+ public string Name
+ {
+ get
+ {
+ return this._Name;
+ }
+ set
+ {
+ if ((this._Name != value))
+ {
+ this.OnNameChanging(value);
+ this.SendPropertyChanging();
+ this._Name = value;
+ this.SendPropertyChanged("Name");
+ this.OnNameChanged();
+ }
+ }
+ }
+
+ [Association(Name="Department_Person", Storage="_Persons", ThisKey="DepartmentId", OtherKey="DepartmentId")]
+ public EntitySet Persons
+ {
+ get
+ {
+ return this._Persons;
+ }
+ set
+ {
+ this._Persons.Assign(value);
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ private void attach_Persons(Person entity)
+ {
+ this.SendPropertyChanging();
+ entity.Department = this;
+ }
+
+ private void detach_Persons(Person entity)
+ {
+ this.SendPropertyChanging();
+ entity.Department = null;
+ }
+ }
+}
+#pragma warning restore 1591
diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClassesSerializationTests.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClassesSerializationTests.cs
new file mode 100644
index 00000000..c2151729
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClassesSerializationTests.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Tests.LinqToSql;
+using NUnit.Framework;
+using System.Reflection;
+using System.ComponentModel;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+ public class LinqToSqlClassesSerializationTests : TestFixtureBase
+ {
+ [Test]
+ public void Serialize()
+ {
+ Role role = new Role();
+ role.Name = "Role1";
+ role.RoleId = new Guid("67EA92B7-4BD3-4718-BD75-3C7EDF800B34");
+
+ Person person = new Person();
+ person.FirstName = "FirstName!";
+ person.LastName = "LastName!";
+ person.PersonId = new Guid("7AA027AA-C995-4986-908D-999D8063599F");
+ person.PersonRoles.Add(new PersonRole
+ {
+ PersonRoleId = new Guid("B012DD41-71DF-4839-B8D5-D1333FB886BC"),
+ Role = role
+ });
+
+ person.Department = new Department
+ {
+ DepartmentId = new Guid("08F68BF9-929B-4434-BC47-C9489D22112B"),
+ Name = "Name!"
+ };
+
+ string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
+
+ Assert.AreEqual(@"{
+ ""first_name"": ""FirstName!"",
+ ""LastName"": ""LastName!"",
+ ""PersonId"": ""7aa027aa-c995-4986-908d-999d8063599f"",
+ ""DepartmentId"": ""08f68bf9-929b-4434-bc47-c9489d22112b"",
+ ""PersonRoles"": [
+ {
+ ""PersonId"": ""7aa027aa-c995-4986-908d-999d8063599f"",
+ ""RoleId"": ""67ea92b7-4bd3-4718-bd75-3c7edf800b34"",
+ ""PersonRoleId"": ""b012dd41-71df-4839-b8d5-d1333fb886bc"",
+ ""Role"": {
+ ""Name"": ""Role1"",
+ ""RoleId"": ""t5LqZ9NLGEe9dTx+34ALNA==""
+ }
+ }
+ ],
+ ""Department"": {
+ ""DepartmentId"": ""08f68bf9-929b-4434-bc47-c9489d22112b"",
+ ""Name"": ""!emaN""
+ }
+}", json);
+ }
+
+ [Test]
+ public void Deserialize()
+ {
+ string json = @"{
+ ""first_name"": ""FirstName!"",
+ ""LastName"": ""LastName!"",
+ ""PersonId"": ""7aa027aa-c995-4986-908d-999d8063599f"",
+ ""PersonRoles"": [
+ {
+ ""PersonId"": ""7aa027aa-c995-4986-908d-999d8063599f"",
+ ""RoleId"": ""67ea92b7-4bd3-4718-bd75-3c7edf800b34"",
+ ""PersonRoleId"": ""b012dd41-71df-4839-b8d5-d1333fb886bc"",
+ ""Role"": {
+ ""Name"": ""Role1"",
+ ""RoleId"": ""t5LqZ9NLGEe9dTx+34ALNA==""
+ }
+ }
+ ],
+ ""Department"": {
+ ""DepartmentId"": ""08f68bf9-929b-4434-bc47-c9489d22112b"",
+ ""Name"": ""!emaN""
+ }
+}";
+
+ Person person = JsonConvert.DeserializeObject(json);
+ Assert.IsNotNull(person);
+
+ Assert.AreEqual(new Guid("7AA027AA-C995-4986-908D-999D8063599F"), person.PersonId);
+ Assert.AreEqual("FirstName!", person.FirstName);
+ Assert.AreEqual("LastName!", person.LastName);
+ Assert.AreEqual(1, person.PersonRoles.Count);
+ Assert.AreEqual(person.PersonId, person.PersonRoles[0].PersonId);
+ Assert.AreEqual(new Guid("67EA92B7-4BD3-4718-BD75-3C7EDF800B34"), person.PersonRoles[0].RoleId);
+ Assert.IsNotNull(person.PersonRoles[0].Role);
+ Assert.AreEqual(1, person.PersonRoles[0].Role.PersonRoles.Count);
+
+ Assert.AreEqual("Name!", person.Department.Name);
+ }
+ }
+}
diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/Person.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/Person.cs
new file mode 100644
index 00000000..c69ea559
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/Person.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+ [MetadataType(typeof(PersonMetadata))]
+ public partial class Person
+ {
+ public class PersonMetadata
+ {
+ [JsonProperty("first_name")]
+ public string FirstName { get; set; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/Role.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/Role.cs
new file mode 100644
index 00000000..f00ad0da
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/LinqToSql/Role.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Data.Linq;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+ [MetadataType(typeof(RoleMetadata))]
+ public partial class Role
+ {
+ public class RoleMetadata
+ {
+ [JsonConverter(typeof(GuidByteArrayConverter))]
+ public Guid RoleId { get; set; }
+ [JsonIgnore]
+ public EntitySet PersonRoles { get; set; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
index 2ad6a174..8e0ed9ef 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
@@ -50,6 +50,9 @@
..\Lib\nunit.framework.dll
+
+ 3.5
+
3.5
@@ -83,6 +86,17 @@
+
+
+
+
+
+ True
+ True
+ LinqToSqlClasses.dbml
+
+
+
@@ -166,6 +180,21 @@
Newtonsoft.Json
+
+
+ MSLinqToSQLGenerator
+ LinqToSqlClasses.designer.cs
+ Designer
+
+
+
+
+
+
+
+ LinqToSqlClasses.dbml
+
+