如何在Entity Framework中手动设置实体主键代码第一个数据库? [英] How to manually set entity primary key in Entity Framework code first database?

查看:318
本文介绍了如何在Entity Framework中手动设置实体主键代码第一个数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗯,我有以下模型结构:我有一个类 - DatabaseEntity 这基本上是

  public class DatabaseEntity 
{
public int Id {get;组;

所以每个实体,如产品,类别等将继承 DatabaseEntity 并且具有 Id 属性。另外我有一个典型的 EntityFramework 存储库类与 InsertOrUpdate 方法:

  private readonly DbContext _database; 

public void InsertOrUpdate&TOGY TO TO TO TO&TO TO TO TOTEX(TObject entity)其中TObject:DatabaseEntity
{
if(entity.Id == default(int))
{
//新实体
DbSet< TObject>()。Add(entity);
}
else
{
//现有实体
_database.Entry(entity).State = EntityState.Modified;
}
_database.SaveChanges();
}

然后我从eBay通过eBay api列出我必须添加的类别数据库。基本类别是:

  public class EbayCategory:DatabaseEntity 
{
//它具有Id,因为它继承DatabaseEntity
public string Name {get;组; }
// ...一些其他属性
}

但是,问题是,当我下载这些类别我下载和他们的Id属性,当然这已经有价值。当我尝试将它们保存到数据库时,如下所示:

  public void UpdateCategories(IEnumerable< EbayCategory> newCategories)
{
foreach(newCategories中的var newCategory)
{
_repository.InsertOrUpdate(newCategory);
}
}

我面临一些问题...首先, entity.Id!= default(int)因为它具有价值,所以存储库尝试更新此实体,而不是添加,但它不在数据库或上下文中,所以它抛出以下异常:

  System.Data.Entity.Infrastructure.DbUpdateConcurencyException 
存储更新,插入或删除语句影响了意外数量的行(0)。实体可能已被修改或删除,因为实体被加载。刷新ObjectStateManager条目。

...因为它认为有人删除了我要更新的实体。如何保存此InsertOrUpdate逻辑,因为许多项目都是基于此项目,并且可以使用主键()添加项目( EbayCategories ) Id )到数据库,然后像其他实体一样更新/删除它们而不丢弃 EbayCategory.Id 值?

解决方案

要允许您手动生成Ids,您需要具有手动生成的ID的类 - 因此它应该不能从 DatabaseEntity

  public class EbayCategory 
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID
{
get {return base.ID; }
set {base.ID = value; }
}

public string Name {get;组; }
// ...一些其他属性
}

现在你会需要一个不同的 InsertOrUpdate 来处理具有手动生成键的实体:

  public void InsertOrUpdate(EbayCategory entity)
{
if(Find(entity.ID == null)
{
//新实体
DbSet< EbayCategory>() .Add(entity);
}
else
{
//现有实体
_database.Entry(entity).State = EntityState.Modified;
}
_database.SaveChanges();
}


Well, I have the following model structure: I have one class - DatabaseEntity which is basically

public class DatabaseEntity
{
    public int Id { get; set; }
}

so each entity like product, category etc will inherit DatabaseEntity and have Id property. Also I have typical EntityFramework repository class with InsertOrUpdate method:

private readonly DbContext _database;

public void InsertOrUpdate<TObject>(TObject entity) where TObject : DatabaseEntity
{
    if(entity.Id == default(int))
    {
         // New entity
         DbSet<TObject>().Add(entity);
    }
    else
    {
         // Existing entity
         _database.Entry(entity).State = EntityState.Modified;
    }
    _database.SaveChanges();
}

Then I download from eBay via eBay api list of categoies I have to add to database. Basically category is:

public class EbayCategory : DatabaseEntity
{
    // It has Id since it inherits DatabaseEntity
    public string Name { get; set; }      
    // ... some other properties
}

But, the problem is, when I download those categories I download and their Id properties, which, of course, already have values. And when I try to save them to database like:

public void UpdateCategories(IEnumerable<EbayCategory> newCategories)
{
    foreach (var newCategory in newCategories)
    {
        _repository.InsertOrUpdate(newCategory);
    }
}

I face some issues... First of all, entity.Id != default(int) because it has value, so repository tries to update this entity, instead of adding, but it is not in the database or context so it throws the following exception:

System.Data.Entity.Infrastructure.DbUpdateConcurencyException
"Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries."

... because it thinks that someone else deleted entity which I am trying to update. How can I save this InsertOrUpdate logic, since a lot of projects are based on it, and be able to add items (EbayCategories) with primary key (Id) to database and then update/delete them like other entities without discarding EbayCategory.Id value?

解决方案

To allow you to manually generate Ids you need a class that has a manually generated ID - so it should probably not inherit from DatabaseEntity

public class EbayCategory
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ID
    {
        get { return base.ID; }
        set { base.ID = value; }
    }

    public string Name { get; set; }      
    // ... some other properties
}

Now you will need a different InsertOrUpdate to handle entities that have manually generated keys:

public void InsertOrUpdate(EbayCategory entity)
{
    if(Find(entity.ID == null)
    {
         // New entity
         DbSet<EbayCategory>().Add(entity);
    }
    else
    {
         // Existing entity
         _database.Entry(entity).State = EntityState.Modified;
    }
    _database.SaveChanges();
}

这篇关于如何在Entity Framework中手动设置实体主键代码第一个数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆