【问题标题】:The ID field of the BaseEntity keeps increasing when insert a new data to different tables in MVC在 MVC 中向不同表插入新数据时 BaseEntity 的 ID 字段不断增加
【发布时间】:2018-01-15 12:57:10
【问题描述】:

我正在使用工作单元和存储库制作一个 MVC 项目。我将我的模型、控制器和映射等分离到解决方案中的不同库中。在使用基本实体时,我碰巧遇到了一个问题,即我用于基于基本实体的多个表的 ID 在这种情况下会增加。当我向表 A 插入新数据时,EX 的 ID 自动增加:1,但是当我向表 B 插入新数据时,ID 增加其值 A 的值,表 B 的第一个数据的 ID 值为 2 . 我怎样才能设法将表之间的 ID 分开以增加 TABLE 的当前值而不是 TABLE 所基于的 BASE ENTITY 的当前值? 这是我的基础实体:

namespace Thaco_Model.Model
{
    public interface IBaseEntities
    {
        long ID { get; set; }
        String name { get; set; }
    }
    public class BaseEntities : IBaseEntities
    {
        [Key]
        public long ID { get; set; }
        public String name { get; set; }
        public HttpStatusCode StatusCode { get; set; }
        public Boolean IsDelete { get; set; }
        public int creator_ID { get; set; }
        public Nullable<int> editor_ID { get; set; }
        public Nullable<DateTime> created_Date { get; set; }
        public Nullable<DateTime> edited_Date { get; set; }
    }
}

这是我的A桌

namespace Thaco_Model.Model
{
    [Table("ValueFlag")]
    public class Value_Flag :BaseEntities
    {
    }
}

这是我的 B 桌:

namespace Thaco_Model.Model
{
    [Table("DefinedValue")]
    public class Defined_Value : BaseEntities
    {
        public long flag_ID { get; set; }
    }
}

这是我的存储库:

namespace Data
{
    public class Repository<T> : IRepository<T> where T : BaseEntities
    {
        private readonly DB_ver_5 context;
        private IDbSet<T> entities;
        string errorMessage = string.Empty;

        public Repository(DB_ver_5 context)
        {
            this.context = context;
        }
        public T GetById(object id)
        {
            return this.Entities.Find(id);
        }

        public void Insert(T entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");
                }
                this.Entities.Add(entity);
                this.context.SaveChanges();
            }
            catch (DbEntityValidationException dbEx)
            {

                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        errorMessage += string.Format("Property: {0} Error: {1}",
                        validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine;
                    }
                }
                throw new Exception(errorMessage, dbEx);
            }
        }

        public void Update(T entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");
                }
                this.context.SaveChanges();
            }
            catch (DbEntityValidationException dbEx)
            {
                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        errorMessage += Environment.NewLine + string.Format("Property: {0} Error: {1}",
                        validationError.PropertyName, validationError.ErrorMessage);
                    }
                }

                throw new Exception(errorMessage, dbEx);
            }
        }

        public void Delete(T entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new ArgumentNullException("entity");
                }

                this.Entities.Remove(entity);
                this.context.SaveChanges();
            }
            catch (DbEntityValidationException dbEx)
            {

                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        errorMessage += Environment.NewLine + string.Format("Property: {0} Error: {1}",
                        validationError.PropertyName, validationError.ErrorMessage);
                    }
                }
                throw new Exception(errorMessage, dbEx);
            }
        }
        public virtual IQueryable<T> Table
        {
            get
            {
                return this.Entities;
            }
        }

        private IDbSet<T> Entities
        {
            get
            {
                if (entities == null)
                {
                    entities = context.Set<T>();
                }
                return entities;
            }
        }
    }

}

【问题讨论】:

  • 向我们展示您的代码。基础实体和至少一个子类
  • 我要归档的是表A和表B的数据ID都是从1开始的,不是根据彼此当前ID计算的,还有一件事,我不使用任何外国键入这个模型,我使用代码优先来创建这些实体
  • 您可以从样本中删除 usings,它只占用空间。好的,您的基础存储库看起来如何?

标签: c# sql-server entity-framework asp.net-mvc-5 n-tier-architecture


【解决方案1】:

其实这是正常的,在EF之前。

您有一个具有主键的基实体类。当您使此类成为其他类的父类时,Entity Framework 正在考虑您确实想要共享属性。如果您查看您的数据库,您应该会看到ValueFlag 没有IDDefinedValue 也是如此。这是因为您的共享属性必须位于名为BaseEntity 的表中。通过这样做,EF 实现了“共享属性”的可能性。

如果您想拥有单独的 ID,您需要将 EF 行为从 TPT 更改为 TPC:https://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and-choosing-strategy-guidelines

另外,请考虑继承对于小表来说通常很好并且足够好。当涉及到大数据时,由于 JOINS 的增加,它显示出一些性能问题(除了 EF“正常”性能问题)。

【讨论】:

  • 我不知道您是否称他们在任何一张桌子上都没有 ID,但我想接近“不要重复自己”,就像有些实体重复在不同的表中多次,所以我尝试使用关系为每个具有相同实体的表提供这些 BaseEntities 以使其更容易和更短的代码。
  • 我真的不明白你想说什么......无论哪种方式,数据库和“源代码”是两个不同的东西。大多数时候,您不能将一个规则和原则应用于另一个。因此,即使可以在数据库上下文中实现“不要重复自己”,也需要付出代价。在您的情况下,付出的代价是共享身份(以及其他事情,但这不是重点)。如果你不想这样,你必须使用另一种方法,如 TPC,如上所示。
  • 感谢您的帮助,我真的很感激
猜你喜欢
  • 2016-06-15
  • 1970-01-01
  • 1970-01-01
  • 2020-05-31
  • 1970-01-01
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多