简体   繁体   English

EF CORE 5.0.1 配置抽象 class 作为 model 实体被忽略,但在派生模型中访问其属性

[英]EF CORE 5.0.1 Configuring abstract class to be ignored as an model entity but access its properties in derived models

I have an abstract base class that is foundation for all derived (~100) classes.我有一个抽象基础 class ,它是所有派生(~100)类的基础。 This base class should not be saved to the database but its properties should be exposed as columns in the derived classes -> entity models.此基础 class不应保存到数据库中,但其属性应作为派生类 -> 实体模型中的列公开。 In the Db context code (OnModel Creation etc), there is NO mention of BaseEntity - only of its derived classes.在 Db 上下文代码(OnModel Creation 等)中,没有提及 BaseEntity - 仅提及其派生类。

In 3.0.1, this worked fine.在 3.0.1 中,这很好用。 BaseEntity was ignored and only mentioned classes (via DbSet or in the OnModelxxx) were configured as TPH. BaseEntity 被忽略,仅提到的类(通过 DbSet 或 OnModelxxx 中)被配置为 TPH。

System.InvalidOperationException: Cannot create a DbSet for 'BaseEntity' because this type is not included in the model for the context. System.InvalidOperationException:无法为“BaseEntity”创建 DbSet,因为此类型未包含在上下文的 model 中。

How do I get back to my previous behavior?我如何恢复以前的行为?


My base class:我的基础 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()保存代码 - 使用 BaseEntity - 在 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;
                    }
                }
            }
ontext.Set<BaseEntity>()

is definitely wrong.肯定是错的。

either use要么使用

context.Add(e);

or或者

context.Set<{ConcreteType}>.Add(e);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM