I have an abstract base class that is foundation for all derived (~100) classes. This base class should not be saved to the database but its properties should be exposed as columns in the derived classes -> entity models. In the Db context code (OnModel Creation etc), there is NO mention of BaseEntity - only of its derived classes.
In 3.0.1, this worked fine. BaseEntity was ignored and only mentioned classes (via DbSet or in the OnModelxxx) were configured as TPH.
System.InvalidOperationException : Cannot create a DbSet for 'BaseEntity' because this type is not included in the model for the context.
How do I get back to my previous behavior?
My base class:
public abstract class BaseEntity
{
[Key]
[GraphQLName("id")]
[GraphQLNonNullType(IsNullable = true)]
public Guid Identifier { get; set; } = Guid.NewGuid();
[GraphQLNonNullType(IsNullable = true)]
public DateTime CreatedDate { get; set; } = DateTime.UtcNow;
[GraphQLNonNullType(IsNullable = true)]
public DateTime LastModifiedDate { get; set; } = DateTime.UtcNow;
[GraphQLNonNullType(IsNullable = true)]
public DateTime DisplayDate { get; set; } = DateTime.UtcNow;
public string DisplayName { get; set; } = string.Empty;
public string DisplayText { get; set; } = string.Empty;
public string DisplayDescription { get; set; } = string.Empty;
public string TypeName { get; set; }
}
.....
Examples Derived classes:
public class Document : BaseEntity
{
[GraphQLIgnore]
public Organization Organization { get; set; }
[GraphQLNonNullType(IsNullable = true)]
public DocumentType DocumentType { get; set; }
/// <summary>
/// Mimetype of the document
/// </summary>
[GraphQLName("type")]
[GraphQLNonNullType(IsNullable = true)]
public string MimeType { get; set; }
}
Save Code - uses BaseEntity - throws exception on SaveChangesAsync()
public async Task<List<T>> Upsert<T>(List<T> baseEntities, bool isRaiseBaseEntityChangeEvent = true) where T : class
{
var entities = new HashSet<BaseEntity>();
foreach (var b in baseEntities)
{
entities.Add(b as BaseEntity);
TraverseGraph(b as BaseEntity, ref entities);
}
using (var context = GetDbInstance())
{
try
{
foreach (var e in entities)
{
//exists in db
if (e.IsPersistedToDatabase == true)
{
context.Attach(e);
foreach (var entry in context.Entry(e).Properties)
{
try
{
if (entry.Metadata.Name.Equals("CreatedDate"))
{
// Don't allow changing the CreatedDate on existing objects.
entry.IsModified = false;
}
else if (entry.CurrentValue != null && !entry.Metadata.IsPrimaryKey())
{
entry.IsModified = true;
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
continue;
}
}
}
else
{
e.IsPersistedToDatabase = true;
context.Set<BaseEntity>().Add(e);
}
}
//make a copy for the change event
List<BaseEntityEntry> baseEntries = new List<BaseEntityEntry>();
foreach (var e in context.ChangeTracker.Entries())
baseEntries.Add(new BaseEntityEntry()
{
Entity = e.Entity as BaseEntity,
State = e.State
});
await context.SaveChangesAsync();
#region BaseEntity change event raising
if (isRaiseBaseEntityChangeEvent)
{
EventsPublisher.Instance.SignalEntityChange(new BaseEntityChangeEventArgs()
{
Entities = baseEntries
});
}
#endregion
return baseEntities;
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
throw ex;
}
}
}
> Upsert(List baseEntities, bool isRaiseBaseEntityChangeEvent = true) where T : class `code`
– Chris Cardinal Dec 09 '20 at 00:05