Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IsComplexType throws a System.NullReferenceException. #225

Open
wants to merge 24 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions Build/nuget-symbols.cmd
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
rem Pushing Symbols packages to NuGet.org

set version=2.5.0-alpha4
NuGet.exe SetApiKey 5682793e-2994-4016-b7b4-c11be576703b
NuGet.exe push Output\TrackableEntities.Common\TrackableEntities.Common.%version%.symbols.nupkg
NuGet.exe push Output\TrackableEntities.Client\TrackableEntities.Client.%version%.symbols.nupkg
NuGet.exe push Output\TrackableEntities.Client.Net4\TrackableEntities.Client.Net4.%version%.symbols.nupkg
NuGet.exe push Output\TrackableEntities.EF.5\TrackableEntities.EF.5.%version%.symbols.nupkg
NuGet.exe push Output\TrackableEntities.EF.6\TrackableEntities.EF.6.%version%.symbols.nupkg
NuGet.exe push Output\TrackableEntities.Patterns\TrackableEntities.Patterns.%version%.symbols.nupkg
NuGet.exe push Output\TrackableEntities.Patterns.EF.6\TrackableEntities.Patterns.EF.6.%version%.symbols.nupkg
set version=2.5.7
set source=https://nuget.smbsrc.net/
nuget SetApiKey 5682793e-2994-4016-b7b4-c11be576703b
nuget push Output\TrackableEntities.Common\TrackableEntities.Common.%version%.symbols.nupkg -src %source%
nuget push Output\TrackableEntities.Client\TrackableEntities.Client.%version%.symbols.nupkg -src %source%
nuget push Output\TrackableEntities.Client.Net4\TrackableEntities.Client.Net4.%version%.symbols.nupkg -src %source%
nuget push Output\TrackableEntities.EF.5\TrackableEntities.EF.5.%version%.symbols.nupkg -src %source%
nuget push Output\TrackableEntities.EF.6\TrackableEntities.EF.6.%version%.symbols.nupkg -src %source%
nuget push Output\TrackableEntities.Patterns\TrackableEntities.Patterns.%version%.symbols.nupkg -src %source%
nuget push Output\TrackableEntities.Patterns.EF.6\TrackableEntities.Patterns.EF.6.%version%.symbols.nupkg -src %source%
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion ReadMe.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# **Trackable Entities**
## N-Tier Support for Entity Framework with WCF or ASP.NET Web API

[![Build Status](https://www.myget.org/BuildSource/Badge/trackable-entities-ci?identifier=3e829f78-43c0-48e7-804b-a1381797fbc3)](https://www.myget.org/)
[![trackable-entities-ci MyGet Build Status](https://www.myget.org/BuildSource/Badge/trackable-entities-ci?identifier=3e829f78-43c0-48e7-804b-a1381797fbc3)](https://www.myget.org/F/trackable-entities-ci)

[![Join the chat at https://gitter.im/TrackableEntities/trackable-entities](https://badges.gitter.im/TrackableEntities/trackable-entities.svg)](https://gitter.im/TrackableEntities/trackable-entities?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@ public FamilyDbContext(CreateDbOptions createDbOptions = CreateDbOptions.CreateD
Database.SetInitializer(new CreateDatabaseIfNotExists<FamilyDbContext>());
break;
}
//Parents = Set<Parent>();
//Children = Set<Child>();
}

public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Children { get; set; }
public DbSet<Contact> Contacts { get; set; }
public DbSet<ContactDetail> ContactDetails { get; set; }
public DbSet<ContactCategory> ContactCategories { get; set; }
public DbSet<ContactData> ContactDatas { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ public class Contact : ITrackable
[Key]
public int Id { get; set; }

[ForeignKey(nameof(ContactDetail))]
public int ContactDetailId { get; set; }
[ForeignKey(nameof(ContactCategory))]
public int ContactCategoryId { get; set; }

public ContactDetail ContactDetail { get; set; }
public ContactCategory ContactCategory { get; set; }

public ContactData ContactData { get; set; }

[NotMapped]
public TrackingState TrackingState { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@

namespace TrackableEntities.EF.Tests.FamilyModels
{
public class ContactDetail : ITrackable
public class ContactCategory : ITrackable
{
[Key]
public int Id { get; set; }

public string Data { get; set; }
public string CategoryName { get; set; }

[NotMapped]
public TrackingState TrackingState { get; set; }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace TrackableEntities.EF.Tests.FamilyModels
{
public class ContactData : ITrackable
{
[Key, ForeignKey(nameof(Contact))]
public int ContactId { get; set; }

public string Data { get; set; }

public Contact Contact { get; set; }

[NotMapped]
public TrackingState TrackingState { get; set; }

[NotMapped]
public ICollection<string> ModifiedProperties { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using System;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using TrackableEntities.EF.Tests.Contexts;
using Xunit;

Expand Down
208 changes: 188 additions & 20 deletions Source/Tests/TrackableEntities.EF.5.Tests/LoadRelatedEntitiesTests.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration.Configuration;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using TrackableEntities.EF.Tests.Contexts;
#if EF_6
using TrackableEntities.EF6;
using System.Data.Entity.Core.EntityClient;
using System.Data.Entity.Core;
#else
using TrackableEntities.EF5;
using System.Data.EntityClient;
using System.Data;
#endif
using TrackableEntities.EF.Tests;
using TrackableEntities.EF.Tests.Mocks;
using TrackableEntities.EF.Tests.Contexts;
using TrackableEntities.EF.Tests.NorthwindModels;
using TrackableEntities.EF.Tests.FamilyModels;

Expand Down Expand Up @@ -337,25 +333,36 @@ private List<Product> CreateTestProductsWithProductInfo(NorthwindDbContext conte
private List<Contact> CreateTestContactsWithDetails(FamilyDbContext context)
{
// Create test entities
var detail1 = new ContactDetail
var category1 = new ContactCategory
{
Data = "Foo",
CategoryName = "Friends",
};
var contact1 = new Contact
{
ContactDetail = detail1
ContactCategory = category1
};

// Persist entities
context.Contacts.Add(contact1);
context.SaveChanges();

// Create one-to-one related entity
var data1 = new ContactData
{
Data = "Data 1",
ContactId = contact1.Id,
Contact = contact1
};
context.ContactDatas.Add(data1);
context.SaveChanges();

// Detach entities
var objContext = ((IObjectContextAdapter)context).ObjectContext;
objContext.Detach(contact1);

// Clear reference properties
contact1.ContactDetail = null;
contact1.ContactCategory = null;
contact1.ContactData = null;

// Return entities
return new List<Contact> { contact1 };
Expand Down Expand Up @@ -860,24 +867,185 @@ public async void LoadRelatedEntitiesAsync_Should_Populate_Multiple_Employees_Te

#endregion

#region Contact-ContactDetails: Non-Matching ForeignKeys
#region LoadRelatedEntities Callbacks

[Fact]
public void LoadRelatedEntities_OnLoading_Should_Continue()
{
// Arrange
var context = TestsHelper.CreateFamilyDbContext(CreateFamilyDbOptions);
var contact = CreateTestContactsWithDetails(context)[0];
context.Contacts.Attach(contact);

// Act
context.LoadRelatedEntities(contact, true, entities =>
{
contact.TrackingState = TrackingState.Added;
return true;
}, (ex, entities) => true);

// Assert
Assert.NotNull(contact.ContactCategory);
Assert.Equal(contact.ContactCategoryId, contact.ContactCategory.Id);
Assert.Equal(TrackingState.Added, contact.TrackingState);
}

[Fact]
public void LoadRelatedEntities_OnLoading_Should_Replace()
{
// Arrange
var context = TestsHelper.CreateFamilyDbContext(CreateFamilyDbOptions);
var contact = CreateTestContactsWithDetails(context)[0];
context.Contacts.Attach(contact);

// Act
context.LoadRelatedEntities(contact, true, entities =>
{
var contact1 = entities.OfType<Contact>().FirstOrDefault(e => e.Id == contact.Id);
if (contact1 != null)
{
context.Entry(contact1).Reference(e => e.ContactCategory).Load();
context.Entry(contact1).Reference(e => e.ContactData).Load();
return false;
}
return true;
});

// Assert
Assert.NotNull(contact.ContactCategory);
Assert.Equal(contact.ContactCategoryId, contact.ContactCategory.Id);
Assert.NotNull(contact.ContactData);
Assert.Equal(contact.Id, contact.ContactData.ContactId);
}

[Fact]
public void LoadRelatedEntities_OnError_Should_Throw()
{
// Arrange
var context = TestsHelper.CreateFamilyDbContext(CreateFamilyDbOptions);
var contact = CreateTestContactsWithDetails(context)[0];

// Act and Assert
Assert.Throws<EntitySqlException>(() =>
{
context.LoadRelatedEntities(contact, true, null, (ex, entities) => false);
});
}

[Fact]
public void LoadRelatedEntities_Should_Populate_Entities_With_NonMatching_Foreign_Keys()
public void LoadRelatedEntities_OnError_Should_Continue()
{
// Arrange
var context = TestsHelper.CreateFamilyDbContext(CreateFamilyDbOptions);
var contact = CreateTestContactsWithDetails(context)[0];
contact.TrackingState = TrackingState.Added;
context.Contacts.Attach(contact);

// Act
context.LoadRelatedEntities(contact);
context.LoadRelatedEntities(contact, true, null, (ex, entities) =>
{
var contact1 = entities.OfType<Contact>().FirstOrDefault(e => e.Id == contact.Id);
if (contact1 != null)
context.Entry(contact1).Reference(e => e.ContactData).Load();
return true;
});

// Assert
Assert.NotNull(contact.ContactDetail);
Assert.Equal(contact.ContactDetailId, contact.ContactDetail.Id);
Assert.NotNull(contact.ContactCategory);
Assert.Equal(contact.ContactCategoryId, contact.ContactCategory.Id);
Assert.NotNull(contact.ContactData);
Assert.Equal(contact.Id, contact.ContactData.ContactId);
}

#if EF_6
[Fact]
public async Task LoadRelatedEntitiesAsync_OnLoading_Should_Continue()
{
// Arrange
var context = TestsHelper.CreateFamilyDbContext(CreateFamilyDbOptions);
var contact = CreateTestContactsWithDetails(context)[0];
context.Contacts.Attach(contact);

// Act
await context.LoadRelatedEntitiesAsync(contact, true, entities =>
{
contact.TrackingState = TrackingState.Added;
return Task.FromResult(true);
}, (ex, entities) => Task.FromResult(true));

// Assert
Assert.NotNull(contact.ContactCategory);
Assert.Equal(contact.ContactCategoryId, contact.ContactCategory.Id);
Assert.Equal(TrackingState.Added, contact.TrackingState);
}

[Fact]
public async Task LoadRelatedEntitiesAsync_OnLoading_Should_Replace()
{
// Arrange
var context = TestsHelper.CreateFamilyDbContext(CreateFamilyDbOptions);
var contact = CreateTestContactsWithDetails(context)[0];
context.Contacts.Attach(contact);

// Act
await context.LoadRelatedEntitiesAsync(contact, true, async entities =>
{
var contact1 = entities.OfType<Contact>().FirstOrDefault(e => e.Id == contact.Id);
if (contact1 != null)
{
await context.Entry(contact1).Reference(e => e.ContactCategory).LoadAsync();
await context.Entry(contact1).Reference(e => e.ContactData).LoadAsync();
return false;
}
return true;
});

// Assert
Assert.NotNull(contact.ContactCategory);
Assert.Equal(contact.ContactCategoryId, contact.ContactCategory.Id);
Assert.NotNull(contact.ContactData);
Assert.Equal(contact.Id, contact.ContactData.ContactId);
}

[Fact]
public async Task LoadRelatedEntitiesAsync_OnError_Should_Throw()
{
// Arrange
var context = TestsHelper.CreateFamilyDbContext(CreateFamilyDbOptions);
var contact = CreateTestContactsWithDetails(context)[0];

// Act and Assert
await Assert.ThrowsAsync<EntitySqlException>(async () =>
{
await context.LoadRelatedEntitiesAsync(contact, true, null,
(ex, entities) => Task.FromResult(false));
});
}

[Fact]
public async Task LoadRelatedEntitiesAsync_OnError_Should_Continue()
{
// Arrange
var context = TestsHelper.CreateFamilyDbContext(CreateFamilyDbOptions);
var contact = CreateTestContactsWithDetails(context)[0];
context.Contacts.Attach(contact);

// Act
await context.LoadRelatedEntitiesAsync(contact, true, null, async (ex, entities) =>
{
var contact1 = entities.OfType<Contact>().FirstOrDefault(e => e.Id == contact.Id);
if (contact1 != null)
await context.Entry(contact1).Reference(e => e.ContactData).LoadAsync();
return true;
});

// Assert
Assert.NotNull(contact.ContactCategory);
Assert.Equal(contact.ContactCategoryId, contact.ContactCategory.Id);
Assert.NotNull(contact.ContactData);
Assert.Equal(contact.Id, contact.ContactData.ContactId);
}
#endif

#endregion

#region Complex Types
Expand Down Expand Up @@ -916,8 +1084,8 @@ public async void LoadRelatedEntitiesAsync_With_Complex_Types()
// previous call throws exception if not implemented properly.
Assert.True(true);
}
#endif
#endif

#endregion Complex Types
#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@
</Compile>
<Compile Include="FamilyModels\Address.cs" />
<Compile Include="FamilyModels\Contact.cs" />
<Compile Include="FamilyModels\ContactDetail.cs" />
<Compile Include="FamilyModels\ContactData.cs" />
<Compile Include="FamilyModels\ContactCategory.cs" />
<Compile Include="StateInterceptorTests.cs" />
<Compile Include="StateChangeInterceptorTests.cs" />
<Compile Include="Contexts\NorthwindDbContext.cs" />
Expand Down
Loading