C# 实体框架DB5使用DBContext模板生成标识
我是EF的新手,已经阅读了尽可能多的教程,但是有很多相互矛盾的信息。我已经包含了一些代码,以防我的方法出错,但本质上我需要弄清楚如何获取EF以允许DB为标识列生成GUID,目前EF正在写入0 我从ADO.NET实体数据模型开始,在数据库优先的方法中使用了它。我在edmx中手动将所有主键设置为StoreGeneratedPattern=Identity。然后我使用EF5.xDbContext生成器创建了我的类 上下文如下所示:C# 实体框架DB5使用DBContext模板生成标识,c#,entity-framework,ado.net,repository,identity,C#,Entity Framework,Ado.net,Repository,Identity,我是EF的新手,已经阅读了尽可能多的教程,但是有很多相互矛盾的信息。我已经包含了一些代码,以防我的方法出错,但本质上我需要弄清楚如何获取EF以允许DB为标识列生成GUID,目前EF正在写入0 我从ADO.NET实体数据模型开始,在数据库优先的方法中使用了它。我在edmx中手动将所有主键设置为StoreGeneratedPattern=Identity。然后我使用EF5.xDbContext生成器创建了我的类 上下文如下所示: public partial class Assets : DbCon
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; }
}
公共部分类资产:DbContext
{
公共资产()
:base(Common.GetConnString(typeof(Assets)))
{
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
抛出新代码FirstException();
}
公共数据库集建筑物{get;set;}
公共数据库集设备{get;set;}
公共数据库集位置{get;set;}
公共数据库集制造商{get;set;}
公共数据库集模型{get;set;}
公共数据库集操作系统{get;set;}
}
这些实体都非常相似,下面是一个实体的外观:
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; }
}
公共部分类设备:iguidd
{
公共Guid ID{get;set;}
公共Guid模型ID{get;set;}
公共可空操作系统ID{get;set;}
公共Guid位置ID{get;set;}
公共字符串DeviceName{get;set;}
公共字符串说明{get;set;}
公共字节[]BinaryIPAddress{get;set;}
公共字符串IP地址
{
得到
{
if(this.binaryPaddress==null)
返回null;
返回字符串.Join(“.”,this.binaryPaddress);
}
设置
{
this.binaryPaddress=System.Net.IPAddress.Parse(value.GetAddressBytes();
}
}
公共虚拟位置{get;set;}
公共虚拟模型模型{get;set;}
公共虚拟操作系统操作系统{get;set;}
}
如果我创建了一个新设备并保存了它,我将写入新设备中定义的GUID,它是00000,而不是遵守edmx中定义的设置。。。我通过unitofwork和repository模式进行保存
工作单位:
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.
}
公共类UnitOfWork:UnitOfWorkBase
{
专用存储库_deviceposition;
公共存储库设备存储库
{
得到
{
如果(_DevicePository==null)
_DevicePository=新存储库(base.Context);
返回设备位置;
}
}
公共工作单元()
:base(新模型.Assets())
{
}
}
公共类UnitOfWorkBase:IDisposable
{
私有只读DbContext\u context;
受保护的DbContext上下文
{
获取{return\u context;}
}
公共UnitOfWorkBase(DbContext上下文)
{
_上下文=上下文;
}
公共作废保存()
{
_SaveChanges();
}
//附加代码等。
}
存储库:
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;
}
}
公共类存储库:GenericRepository
其中tenty:class,iguiid
{
公共存储库(DbContext上下文)
:基本(上下文)
{
}
//此处的附加代码(包含等)
}
公共类GenericRepository,其中tenty:类
{
私有只读DbContext\u context;
私有只读数据库集_DbSet;
公共GenericRepository(DbContext上下文)
{
_上下文=上下文;
_dbSet=context.Set();
}
公共虚拟IEnumerable All()
{
返回_dbSet.AsEnumerable();
}
公共虚拟无效删除(TEntity entityToDelete)
{
if(_context.Entry(entityToDelete.State==EntityState.Detached)
_数据库集连接(entityToDelete);
_dbSet.Remove(entityToDelete);
}
公共虚拟空白插入(TEntity实体)
{
_添加(实体);
}
公共虚拟无效更新(TEntity entityToUpdate)
{
if(_context.Entry(entityToUpdate.State==EntityState.Detached)
_数据库集附加(实体更新);
_context.Entry(entityToUpdate.State=EntityState.Modified;
}
}
老实说,这种行为并不让我感到惊讶,如果我连接了一个带有0000的设备。。。ID我希望它能像这样插入,但我不确定如何解决或哪里出了问题。即使我的ID不在数据库中,它们也应该为空吗?我需要对映射做些什么吗?当我还在使用LINQtoSQL时,这种方法就“起作用了”
谢谢-Derrick我认为您需要将以下属性应用于GUID属性
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }
您需要将以下命名空间添加到类中
using System.ComponentModel.DataAnnotations.Schema;
我找到了解决办法。实际上,通过VisualStudio中的属性编辑edmx文件只会改变概念模型。我还需要修改StorageModels,我不知道是否还有其他方法,但是手动修改XML对我来说很有效。我必须将StoreGeneratedPattern=“Identity”添加到主键属性
<EntityType Name="Devices">
<Key>
<PropertyRef Name="DeviceID" />
</Key>
<Property Name="DeviceID" Type="uniqueidentifier" Nullable="false" StoreGeneratedPattern="Identity" />
<!--Additional Properties-->
我之前试过,你可能是对的,但这似乎不是唯一缺少的东西。