C# 实体框架DB5使用DBContext模板生成标识

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

我是EF的新手,已经阅读了尽可能多的教程,但是有很多相互矛盾的信息。我已经包含了一些代码,以防我的方法出错,但本质上我需要弄清楚如何获取EF以允许DB为标识列生成GUID,目前EF正在写入0

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

上下文如下所示:

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-->

我之前试过,你可能是对的,但这似乎不是唯一缺少的东西。