Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 4.0 如何使用UnitOfWork模式和代码优先实体框架防止重复条目?_C# 4.0_Entity Framework 4.1_Ef Code First_Sql Server 2008 R2 - Fatal编程技术网

C# 4.0 如何使用UnitOfWork模式和代码优先实体框架防止重复条目?

C# 4.0 如何使用UnitOfWork模式和代码优先实体框架防止重复条目?,c#-4.0,entity-framework-4.1,ef-code-first,sql-server-2008-r2,C# 4.0,Entity Framework 4.1,Ef Code First,Sql Server 2008 R2,我使用的是工作单元和通用存储库模式。以下是检查重复条目的语句: int id = int.Parse(beer.id); //id comes from the item we're hoping to insert if (_unitOfWork.BeerRepository.GetByID(id) == null) \\create a new model br _unitOfWork.BeerRepository.Insert(br); _unitOfWor

我使用的是工作单元和通用存储库模式。以下是检查重复条目的语句:

int id = int.Parse(beer.id); //id comes from the item we're hoping to insert

if (_unitOfWork.BeerRepository.GetByID(id) == null)
     \\create a new model br
     _unitOfWork.BeerRepository.Insert(br);
     _unitOfWork.save();
显然,这无法检查啤酒是否已经在数据库中,因为我得到了以下内部异常:

违反主键约束“PK_Beers_3214EC2703317E3D”。 无法在对象“dbo.Beers”中插入重复的键。\r\n语句 已经终止

我也得到了这样的信息:

保存不公开外部数据的实体时出错 其关系的关键属性。EntityEntries属性 将返回null,因为无法将单个实体标识为 异常的来源。可以在保存时处理异常 通过在实体类型中公开外键属性变得更容易。 有关详细信息,请参见InnerException

UnitOfWork类具有实现DbContext的my BeerRecomdaterContext,UnitOfWork具有每个实体的通用存储库:

namespace BeerRecommender.Models
{
public class GenericRepository<TEntity> where TEntity : class
{
    internal BeerRecommenderContext context;
    internal DbSet<TEntity> dbSet;

    public GenericRepository(BeerRecommenderContext context)
    {
        this.context = context;
        this.dbSet = context.Set<TEntity>();
    }

    public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<TEntity> query = dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }

    public virtual TEntity GetByID(object id)
    {
        return dbSet.Find(id);
    }

    public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
    }

    public virtual void Delete(object id)
    {
        TEntity entityToDelete = dbSet.Find(id);
        Delete(entityToDelete);
    }

    public virtual void Delete(TEntity entityToDelete)
    {
        if (context.Entry(entityToDelete).State == EntityState.Detached)
        {
            dbSet.Attach(entityToDelete);
        }
        dbSet.Remove(entityToDelete);
    }

    public virtual void Update(TEntity entityToUpdate)
    {
        dbSet.Attach(entityToUpdate);
        context.Entry(entityToUpdate).State = EntityState.Modified;
    }

    }
}
名称空间BeerRecommender.Models
{
公共类GenericRepository,其中tenty:类
{
内部BeerreCommanderContext;
内部数据库集;
公共一般报告(BeerRecomrderContext)
{
this.context=上下文;
this.dbSet=context.Set();
}
公共虚拟IEnumerable Get(
表达式筛选器=空,
Func orderBy=null,
字符串includeProperties=“”)
{
IQueryable query=dbSet;
if(过滤器!=null)
{
query=query.Where(过滤器);
}
foreach(includeProperty.Split中的var includeProperty
(新字符[]{',},StringSplitOptions.RemoveEmptyEntries)
{
query=query.Include(includeProperty);
}
if(orderBy!=null)
{
returnorderby(query.ToList();
}
其他的
{
返回query.ToList();
}
}
公共虚拟实体GetByID(对象id)
{
返回dbSet.Find(id);
}
公共虚拟空白插入(TEntity实体)
{
添加(实体);
}
公共虚拟无效删除(对象id)
{
TEntity entityToDelete=dbSet.Find(id);
删除(entityToDelete);
}
公共虚拟无效删除(TEntity entityToDelete)
{
if(context.Entry(entityToDelete.State==EntityState.Detached)
{
数据库集连接(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
公共虚拟无效更新(TEntity entityToUpdate)
{
数据库集附加(实体更新);
context.Entry(entityToUpdate.State=EntityState.Modified;
}
}
}

我对使用代码优先的存储库也有类似的用法。偶尔,我会看到像你描述的那样的冲突。我的问题是跨多个流程跟踪更改。是否在一个进程内(使用单个实体上下文)将项插入数据库

如果是,您应该查看EntityFramework提供的合并选项。如果您使用默认的合并选项(AppendOnly),那么您可以查询内存中的上下文,而不是转到数据库。这可能导致您描述的行为

不幸的是,据我所知,所有的合并选项还没有首先向代码公开。您可以选择默认值(AppendOnly)或NoTracking,每次都会转到数据库

希望这有帮助,
Davin

我对使用代码优先的存储库也有类似的用法。偶尔,我会看到像你描述的那样的冲突。我的问题是跨多个流程跟踪更改。是否在一个进程内(使用单个实体上下文)将项插入数据库

如果是,您应该查看EntityFramework提供的合并选项。如果您使用默认的合并选项(AppendOnly),那么您可以查询内存中的上下文,而不是转到数据库。这可能导致您描述的行为

不幸的是,据我所知,所有的合并选项还没有首先向代码公开。您可以选择默认值(AppendOnly)或NoTracking,每次都会转到数据库

希望这有帮助,
Davin

您是否将新车型的主键属性
br
设置为
id
?我的车型类别的主键是“id”。当一个新的啤酒被创建时,我使用给定的ID,这实际上应该是可行的。你做了一些非常简单的检查吗?例如:1)注意您正在测试的
id
,例如
5
。2) 查看数据库中是否有键=
5
的啤酒。3) 检查
GetByID
->的结果如果数据库中有啤酒编号5,但
GetByID
返回
null
,停止使用EF并喝下数据库中的所有啤酒。如果没有啤酒号码5且
GetByID
返回
null
(这是预期的),则在调用insert之前,在调试器中检查新啤酒的ID是否为5。等等,等等,等等。您是否将新型号的主键属性
br
设置为
id
?我的型号类的主键是“id”。当一个新的啤酒被创建时,我使用给定的ID,这实际上应该是可行的。你做了一些非常简单的检查吗?例如:1)注意您正在测试的
id
,例如
5
。2) 查看数据库中是否有键=
5
的啤酒。3) 检查
GetByID
->的结果如果数据库中有啤酒编号5,但
GetByID
返回
null
,停止使用EF并喝下数据库中的所有啤酒。如果没有啤酒号码5且
GetByID
返回
null
(这是预期的),则在调用insert之前,在调试器中检查新啤酒的ID是否为5。等等,等等,等等,我只是用一个过程来做这件事