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

Add GetDbSets and fix error details of incorrect Entity type full name #23946

Merged
merged 28 commits into from
Jan 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
bec7617
Merge pull request #1 from Ali-YousefiTelori/origin/main
Ali-YousefiTelori Jan 13, 2021
228a73a
Bump Microsoft.AspNetCore.OData from 7.5.2 to 7.5.4
dependabot[bot] Jan 13, 2021
afb15f2
Bump Microsoft.Azure.Cosmos from 3.15.1 to 3.16.0
dependabot[bot] Jan 13, 2021
a36813f
Add support for GetDbSets to get every DbSets that your context have …
Ali-YousefiTelori Jan 23, 2021
1d1fda2
change the message of
Ali-YousefiTelori Jan 23, 2021
bc8a746
Merge pull request #3 from Ali-YousefiTelori/dependabot/nuget/Microso…
Ali-YousefiTelori Jan 23, 2021
13d5648
Merge pull request #2 from Ali-YousefiTelori/dependabot/nuget/Microso…
Ali-YousefiTelori Jan 23, 2021
0e761f4
Revert "Bump Microsoft.Azure.Cosmos from 3.15.1 to 3.16.0"
Ali-YousefiTelori Jan 23, 2021
8cda333
Merge pull request #5 from Ali-YousefiTelori/revert-3-dependabot/nuge…
Ali-YousefiTelori Jan 23, 2021
ee56370
Revert "Bump Microsoft.AspNetCore.OData from 7.5.2 to 7.5.4"
Ali-YousefiTelori Jan 23, 2021
093921e
Merge pull request #6 from Ali-YousefiTelori/revert-2-dependabot/nuge…
Ali-YousefiTelori Jan 23, 2021
0cea4d8
add context.GetDbSets().Select(dbSetType => dbSetType.Value.FullName)…
Ali-YousefiTelori Jan 23, 2021
9468168
Merge branch 'dev' of https://github.com/Ali-YousefiTelori/EntityFram…
Ali-YousefiTelori Jan 23, 2021
6030692
add typeof and user FullName to fix tests of new InvalidSetType message
Ali-YousefiTelori Jan 23, 2021
22e9e52
make GetDbSets as virtual
Ali-YousefiTelori Jan 23, 2021
694176c
add CheckDisposed to GetDbSets()
Ali-YousefiTelori Jan 23, 2021
44954c6
add CheckDispose in test cases of GetDbSets
Ali-YousefiTelori Jan 23, 2021
85131ed
fix List<T> of GetDbSets return type
Ali-YousefiTelori Jan 23, 2021
5cf470a
add CanBeNull attribute for yourTypes argument in InvalidSetType method
Ali-YousefiTelori Jan 23, 2021
dd38861
add tuple (string PropertyName, string TableName, Type EntityType) in…
Ali-YousefiTelori Jan 24, 2021
cbde64e
fix null annotatable of tableName
Ali-YousefiTelori Jan 24, 2021
9e73d00
fix null annotatable of entityType
Ali-YousefiTelori Jan 24, 2021
fefa3b0
Remove GetDbSets and use GetEntityTypes
Ali-YousefiTelori Jan 25, 2021
b783bf6
add and fix DisplayName instade of Full name of type to display gener…
Ali-YousefiTelori Jan 26, 2021
a83d6e2
Add Different exception throwing for same type name with different na…
Ali-YousefiTelori Jan 27, 2021
a617107
fix usage of Throws_for_bad_entity_type_with_different_namespace and …
Ali-YousefiTelori Jan 27, 2021
7f4f935
Update src/EFCore/Properties/CoreStrings.resx
Ali-YousefiTelori Jan 28, 2021
5157fed
move FindSameTypeNameWithDifferentNamespace to Microsoft.EntityFramew…
Ali-YousefiTelori Jan 28, 2021
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
15 changes: 13 additions & 2 deletions src/EFCore/DbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -138,7 +139,8 @@ public virtual ChangeTracker ChangeTracker
/// </summary>
public virtual IModel Model
{
[DebuggerStepThrough] get => DbContextDependencies.Model;
[DebuggerStepThrough]
get => DbContextDependencies.Model;
}

/// <summary>
Expand Down Expand Up @@ -311,7 +313,16 @@ private IEntityFinder Finder(Type type)
throw new InvalidOperationException(CoreStrings.InvalidSetSharedType(type.ShortDisplayName()));
}

throw new InvalidOperationException(CoreStrings.InvalidSetType(type.ShortDisplayName()));
var findSameTypeName = Model.FindSameTypeNameWithDifferentNamespace(type);
//if the same name exists in your entity types we will show you the full namespace of the type
if (!string.IsNullOrEmpty(findSameTypeName))
{
throw new InvalidOperationException(CoreStrings.InvalidSetSameTypeWithDifferentNamespace(type.DisplayName(), findSameTypeName));
}
else
{
throw new InvalidOperationException(CoreStrings.InvalidSetType(type.ShortDisplayName()));
}
}

if (entityType.FindPrimaryKey() == null)
Expand Down
12 changes: 11 additions & 1 deletion src/EFCore/Internal/InternalDbSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Utilities;

Expand Down Expand Up @@ -81,7 +82,16 @@ public override IEntityType EntityType
throw new InvalidOperationException(CoreStrings.InvalidSetSharedType(typeof(TEntity).ShortDisplayName()));
}

throw new InvalidOperationException(CoreStrings.InvalidSetType(typeof(TEntity).ShortDisplayName()));
var findSameTypeName = _context.Model.FindSameTypeNameWithDifferentNamespace(typeof(TEntity));
//if the same name exists in your entity types we will show you the full namespace of the type
if (!string.IsNullOrEmpty(findSameTypeName))
{
throw new InvalidOperationException(CoreStrings.InvalidSetSameTypeWithDifferentNamespace(typeof(TEntity).DisplayName(), findSameTypeName));
}
else
{
throw new InvalidOperationException(CoreStrings.InvalidSetType(typeof(TEntity).ShortDisplayName()));
}
}

if (_entityType.IsOwned())
Expand Down
26 changes: 26 additions & 0 deletions src/EFCore/Metadata/Internal/EntityTypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,5 +404,31 @@ public static IProperty CheckPropertyBelongsToType([NotNull] this IEntityType en
/// </summary>
public static EntityType AsEntityType([NotNull] this IEntityType entityType, [NotNull] [CallerMemberName] string methodName = "")
=> MetadataExtensions.AsConcreteMetadataType<IEntityType, EntityType>(entityType, methodName);



/// <summary>
/// Try to find the name of the type that has a different namespace from your entity types
/// </summary>
/// <param name="model">
/// model Of your context to find entities
/// </param>
/// <param name="type">
/// A Type that you think have a different namespace and exists in your entity types
/// </param>
/// <returns>
/// the name with different namespace found
/// </returns>
public static string? FindSameTypeNameWithDifferentNamespace([NotNull] this IModel model, [NotNull] Type type)
{
//try to find the same name of the entity with type to throw a specific exception
return model.GetEntityTypes()
//check the short names are equals because the namespaces are not equaled we need to check just names are equals
.Where(x => x.ClrType.DisplayName(false) == type.DisplayName(false))
//select the full name of type because we need to show the developer a type with the full name
.Select(x => x.ClrType.DisplayName())
//select one of them to show the developer
.FirstOrDefault();
}
}
}
13 changes: 11 additions & 2 deletions src/EFCore/Properties/CoreStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/EFCore/Properties/CoreStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,9 @@
<data name="InvalidSetType" xml:space="preserve">
<value>Cannot create a DbSet for '{typeName}' because this type is not included in the model for the context.</value>
</data>
<data name="InvalidSetSameTypeWithDifferentNamespace" xml:space="preserve">
<value>Cannot create a DbSet for '{typeName}' because this type is not included in the model for the context. However the model contains an entity type with the same name in a different namespace: '{entityTypeName}'.</value>
</data>
<data name="InvalidSetTypeOwned" xml:space="preserve">
<value>Cannot create a DbSet for '{typeName}' because it is configured as an owned entity type and must be accessed through its owning entity type '{ownerType}'.</value>
</data>
Expand Down
32 changes: 32 additions & 0 deletions test/EFCore.Specification.Tests/FindTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.TestUtilities;
using Xunit;

Expand Down Expand Up @@ -300,11 +301,22 @@ public virtual void Throws_for_bad_type_for_composite_key()
public virtual void Throws_for_bad_entity_type()
{
using var context = CreateContext();

Assert.Equal(
CoreStrings.InvalidSetType(nameof(Random)),
Assert.Throws<InvalidOperationException>(() => Find<Random>(context, 77)).Message);
}

[ConditionalFact]
public virtual void Throws_for_bad_entity_type_with_different_namespace()
{
using var context = CreateContext();

Assert.Equal(
CoreStrings.InvalidSetSameTypeWithDifferentNamespace(typeof(Microsoft.EntityFrameworkCore.DifferentNamespace.ShadowKey).DisplayName(), typeof(ShadowKey).DisplayName()),
Assert.Throws<InvalidOperationException>(() => Find<Microsoft.EntityFrameworkCore.DifferentNamespace.ShadowKey>(context, 77)).Message);
}

[ConditionalFact]
public virtual async Task Find_int_key_tracked_async()
{
Expand Down Expand Up @@ -580,6 +592,17 @@ public virtual async Task Throws_for_bad_entity_type_async()
(await Assert.ThrowsAsync<InvalidOperationException>(() => FindAsync<Random>(context, 77).AsTask())).Message);
}

[ConditionalFact]
public virtual async Task Throws_for_bad_entity_type_with_different_namespace_async()
{
using var context = CreateContext();

Assert.Equal(
CoreStrings.InvalidSetSameTypeWithDifferentNamespace(typeof(Microsoft.EntityFrameworkCore.DifferentNamespace.ShadowKey).DisplayName(), typeof(ShadowKey).DisplayName()),
(await Assert.ThrowsAsync<InvalidOperationException>(() => FindAsync<Microsoft.EntityFrameworkCore.DifferentNamespace.ShadowKey>(context, 77).AsTask())).Message);
}


protected class BaseType
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
Expand Down Expand Up @@ -677,3 +700,12 @@ protected override void Seed(PoolableDbContext context)
}
}
}


namespace Microsoft.EntityFrameworkCore.DifferentNamespace
{
internal class ShadowKey
{
public string Foo { get; set; }
}
}
21 changes: 21 additions & 0 deletions test/EFCore.Tests/DbContextServicesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3671,3 +3671,24 @@ public DerivedContext2(DbContextOptions<DerivedContext2> options)
}
}
}

namespace Microsoft.EntityFrameworkCore.DifferentNamespace
{
internal class Category
{
public int Id { get; set; }
public string Name { get; set; }

public List<Product> Products { get; set; }
}

internal class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }

public int CategoryId { get; set; }
public Category Category { get; set; }
}
}
10 changes: 10 additions & 0 deletions test/EFCore.Tests/DbContextTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,19 @@ public void Set_throws_for_type_not_in_model()

using var context = new DbContext(optionsBuilder.Options);
var ex = Assert.Throws<InvalidOperationException>(() => context.Set<Category>().Local);

Assert.Equal(CoreStrings.InvalidSetType(nameof(Category)), ex.Message);
}

[ConditionalFact]
public void Set_throws_for_type_not_in_model_same_type_with_different_namespace()
{
using var context = new EarlyLearningCenter();
var ex = Assert.Throws<InvalidOperationException>(() => context.Set<Microsoft.EntityFrameworkCore.DifferentNamespace.Category>().Local);

Assert.Equal(CoreStrings.InvalidSetSameTypeWithDifferentNamespace(typeof(Microsoft.EntityFrameworkCore.DifferentNamespace.Category).DisplayName(), typeof(Category).DisplayName()), ex.Message);
}

[ConditionalFact]
public void Local_calls_DetectChanges()
{
Expand Down
1 change: 1 addition & 0 deletions test/EFCore.Tests/DbSetTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ public void Use_of_LocalView_throws_if_context_is_disposed()
public void Using_ignored_entity_that_has_DbSet_on_context_throws_appropriately()
{
using var context = new IgnoredCntext();

Assert.Equal(
CoreStrings.InvalidSetType(nameof(IgnoredEntity)),
Assert.Throws<InvalidOperationException>(() => context.Ignored.ToList()).Message);
Expand Down