我对EF很陌生并且尽可能多地阅读教程,但那里有很多相互矛盾的信息。我已经包含了一些代码以防我的方法错误,但实质上我需要弄清楚如何让EF允许DB为标识列生成GUID,目前EF正在写0。
我从一个ADO.NET实体数据模型开始,我在数据库第一种方法中使用它。我在edmx中手动将所有主键设置为StoreGeneratedPattern = Identity。然后我使用了EF5.x DBContext Generator,这创建了我的类。
上下文如下:
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和存储库模式保存。
的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都应该可以为空,即使它们不在数据库中吗?我需要做一些映射吗?当我还在使用Linq to SQL时,这种事情就“起作用了”。
谢谢 - 德里克
答案 0 :(得分:1)
我认为您需要将以下属性应用于GUID属性
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }
您需要将以下命名空间添加到您的类
using System.ComponentModel.DataAnnotations.Schema;
答案 1 :(得分:1)
我找到了解决方案here。基本上通过VisualStudio中的属性编辑edmx文件只会改变ConceptualModels。我也需要修改StorageModels,我不知道是否有其他方法,但手动修改XML对我有效。我必须将StoreGeneratedPattern =“Identity”添加到主键属性。
<EntityType Name="Devices">
<Key>
<PropertyRef Name="DeviceID" />
</Key>
<Property Name="DeviceID" Type="uniqueidentifier" Nullable="false" StoreGeneratedPattern="Identity" />
<!--Additional Properties-->