实体框架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
我认为您需要将以下属性应用于您的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-->