实体框架5使用DBContext模板生成身份

本文关键字:身份 DBContext 框架 使用 实体 | 更新日期: 2023-09-27 17:50:52

我对EF很陌生,并且已经尽可能多地阅读了教程,但是那里有很多相互矛盾的信息。我已经包括了一些代码,以防我的方法是错误的,但本质上我需要弄清楚如何让EF允许DB为身份列生成GUID,目前EF正在写0。

我从一个ADO开始。. NET实体数据模型,我在数据库优先的方法中使用它。我在edmx中手动将所有主键设置为StoreGeneratedPattern=Identity。然后我用了EF5。x DBContext生成器,这创建了我的类。

上下文看起来像:

public partial class Assets : DbContext
{
    public Assets()
        : base(Common.GetConnString(typeof(Assets)))
    {
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }
    public DbSet<Building> Buildings { get; set; }
    public DbSet<Device> Devices { get; set; }
    public DbSet<Location> Locations { get; set; }
    public DbSet<Manufacturer> Manufacturers { get; set; }
    public DbSet<Model> Models { get; set; }
    public DbSet<OperatingSystem> OperatingSystems { get; set; }
}

这些实体都很相似,下面是一个实体的样子:

public partial class Device : IGuidID
{
    public Guid ID { get; set; }
    public Guid ModelID { get; set; }
    public Nullable<Guid> OperatingSystemID { get; set; }
    public Guid LocationID { get; set; }
    public string DeviceName { get; set; }
    public string Description { get; set; }
    public byte[] BinaryIPAddress { get; set; }
    public string IPAddress
    {
        get
        {
            if (this.BinaryIPAddress == null)
                return null;
            return string.Join(".", this.BinaryIPAddress);
        }
        set
        {
            this.BinaryIPAddress = System.Net.IPAddress.Parse(value).GetAddressBytes();
        }
    }
    public virtual Location Location { get; set; }
    public virtual Model Model { get; set; }
    public virtual OperatingSystem OperatingSystem { get; set; }
}

如果我创建一个新设备并保存它,而不是遵守edmx中定义的设置,我正在编写新设备中定义的GUID,即00000…我正在通过工作单元和存储库模式进行保存。

UnitOfWork:

public class UnitOfWork : UnitOfWorkBase
{
    private Repository<Device> _deviceRepository;
    public Repository<Device> DeviceRepository
    {
        get
        {
            if (_deviceRepository == null)
                _deviceRepository = new Repository<Device>(base.Context);
            return _deviceRepository;
        }
    }
    public UnitOfWork()
        : base(new Model.Assets())
    {
    }
}
public class UnitOfWorkBase : IDisposable
{
    private readonly DbContext _context;
    protected DbContext Context
    {
        get { return _context; }
    }
    public UnitOfWorkBase(DbContext context)
    {
        _context = context;
    }
    public void Save()
    {
        _context.SaveChanges();
    }
    // Additional code Dispose, etc.
}

存储库:

public class Repository<TEntity> : GenericRepository<TEntity>
    where TEntity : class, IGuidID
{
    public Repository(DbContext context)
        : base(context)
    {
    }
    // Additional code here(Contains, etc.)
}
public class GenericRepository<TEntity> where TEntity : class
{
    private readonly DbContext _context;
    private readonly DbSet<TEntity> _dbSet;
    public GenericRepository(DbContext context)
    {
        _context = context;
        _dbSet = context.Set<TEntity>();
    }
    public virtual IEnumerable<TEntity> All()
    {
        return _dbSet.AsEnumerable();
    }
    public virtual void Delete(TEntity entityToDelete)
    {
        if (_context.Entry(entityToDelete).State == EntityState.Detached)
            _dbSet.Attach(entityToDelete);
        _dbSet.Remove(entityToDelete);
    }
    public virtual void Insert(TEntity entity)
    {
        _dbSet.Add(entity);
    }
    public virtual void Update(TEntity entityToUpdate)
    {
        if (_context.Entry(entityToUpdate).State == EntityState.Detached)
            _dbSet.Attach(entityToUpdate);
        _context.Entry(entityToUpdate).State = EntityState.Modified;
    }
}

老实说,这种行为并不让我感到惊讶,如果我连接一个带有0000的设备…ID我希望它这样插入,但我不确定如何解决或哪里出了问题。应该所有我的ID是空的,即使他们不在DB?我需要对映射做些什么吗?当我还在使用Linq to SQL的时候,这种事情只是"工作"。

Thanks - Derrick

实体框架5使用DBContext模板生成身份

我认为您需要将以下属性应用于您的GUID属性

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }

您需要将以下名称空间添加到您的类

using System.ComponentModel.DataAnnotations.Schema;

我在这里找到了一个解决方案。基本上,通过VisualStudio中的属性编辑edmx文件只是改变了ConceptualModels。我还需要修改StorageModels,我不知道是否有其他方法,但是手动修改XML对我来说是有效的。我必须添加StoreGeneratedPattern="Identity"到Primary Key属性。

<EntityType Name="Devices">
    <Key>
        <PropertyRef Name="DeviceID" />
    </Key>
    <Property Name="DeviceID" Type="uniqueidentifier" Nullable="false" StoreGeneratedPattern="Identity" />
    <!--Additional Properties-->