使用EF按id删除记录,如果id不存在,则抛出异常

时间:2015-07-17 02:26:45

标签: c# entity-framework

代码如下所示:

try
{
    Student stu = new Student() { ID = id };
    db.Entry(stu).State = EntityState.Deleted;

    int result = db.SaveChanges();
}
catch (DataException e)
{

}

例外是:

  

存储更新,插入或删除语句会影响意外   行数(0)。自那以后,实体可能已被修改或删除   实体已加载。看到   http://go.microsoft.com/fwlink/?LinkId=472540了解有关的信息   理解和处理乐观并发异常。

...但我不想获得异常,我想获得受影响的行数,例如0

3 个答案:

答案 0 :(得分:1)

试试这个

try{
var student= db.Students.First(x => x.ID== 1);
db.Students.DeleteObject(student);
db.SaveChanges();
}
catch(Exception ex)
{return 0;}

答案 1 :(得分:1)

如果你不介意从数据库中提取实体只是为了删除它们,你可以这样做

SDL_Texture * get_texture(
    SDL_Renderer * pRenderer,
    std::string image_filename) {
    SDL_Texture * result = NULL;

    SDL_Surface * pSurface = IMG_Load(image_filename.c_str());

    if (pSurface == NULL) {
        printf("Error image load: %s\n", IMG_GetError());
    }
    else {
        const int limit = 1024;
        int width = pSurface->w;
        int height = pSurface->h;

        if ((width > limit) ||
            (height > limit)) {
            SDL_Rect sourceDimensions;
            sourceDimensions.x = 0;
            sourceDimensions.y = 0;
            sourceDimensions.w = width;
            sourceDimensions.h = height;

            float scale = (float)limit / (float)width;
            float scaleH = (float)limit / (float)height;

            if (scaleH < scale) {
                scale = scaleH;
            }

            SDL_Rect targetDimensions;
            targetDimensions.x = 0;
            targetDimensions.y = 0;
            targetDimensions.w = (int)(width * scale);
            targetDimensions.h = (int)(height * scale);

            // create a 32 bits per pixel surface to Blit the image to first, before BlitScaled
            // https://stackoverflow.com/questions/33850453/sdl2-blit-scaled-from-a-palettized-8bpp-surface-gives-error-blit-combination/33944312
            SDL_Surface *p32BPPSurface = SDL_CreateRGBSurface(
                pSurface->flags,
                sourceDimensions.w,
                sourceDimensions.h,
                32,
                pSurface->format->Rmask,
                pSurface->format->Gmask,
                pSurface->format->Bmask,
                pSurface->format->Amask);

            if (SDL_BlitSurface(pSurface, NULL, p32BPPSurface, NULL) < 0) {
                printf("Error did not blit surface: %s\n", SDL_GetError());
            }
            else {
                // create another 32 bits per pixel surface are the desired scale
                SDL_Surface *pScaleSurface = SDL_CreateRGBSurface(
                    p32BPPSurface->flags,
                    targetDimensions.w,
                    targetDimensions.h,
                    p32BPPSurface->format->BitsPerPixel,
                    p32BPPSurface->format->Rmask,
                    p32BPPSurface->format->Gmask,
                    p32BPPSurface->format->Bmask,
                    p32BPPSurface->format->Amask);

                // 32 bit per pixel surfaces (loaded from the original file) won't scale down with BlitScaled, suggestion to first fill the surface
                // 8 and 24 bit depth pngs did not require this
                // https://stackoverflow.com/questions/20587999/sdl-blitscaled-doesnt-work
                SDL_FillRect(pScaleSurface, &targetDimensions, SDL_MapRGBA(pScaleSurface->format, 255, 0, 0, 255));

                if (SDL_BlitScaled(p32BPPSurface, NULL, pScaleSurface, NULL) < 0) {
                    printf("Error did not scale surface: %s\n", SDL_GetError());

                    SDL_FreeSurface(pScaleSurface);
                    pScaleSurface = NULL;
                }
                else {
                    SDL_FreeSurface(pSurface);

                    pSurface = pScaleSurface;
                    width = pSurface->w;
                    height = pSurface->h;
                }
            }

            SDL_FreeSurface(p32BPPSurface);
            p32BPPSurface = NULL;
        }

        SDL_Texture * pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurface);

        if (pTexture == NULL) {
            printf("Error image load: %s\n", SDL_GetError());
        }
        else {
            SDL_SetTextureBlendMode(
                pTexture,
                SDL_BLENDMODE_BLEND);

            result = pTexture;
        }

        SDL_FreeSurface(pSurface);
        pSurface = NULL;
    }

    return result;
}

如果您更关心提取条目数据,请使用其中一项检查是否存在,按ID方式删除。

如果您担心减少数据库往返量,请使用类似于以下内容的自定义SQL命令(可能转换为存储过程)。

db.Students.RemoveRange(db.Students.Where(x => x.Id == ID));

但是,如果您选择最后一个示例,我认为您根本不应该使用EF。你失去了抽象,突然需要关心SQL等中的模式和表名。

答案 2 :(得分:0)

它会抛出一个错误,因为你正在附加一个可能根本不存在于数据库中的对象。

所以你需要首先检查它是否存在,如果是,则删除它,否则忽略它或返回该对象不存在的错误代码。

另一种方法是加载对象并调用Remove

try
{
    if(db.Students.Any(s=>s.ID == id)
    {
      Student stu = new Student() { ID = id };
      db.Entry(stu).State = EntityState.Deleted;
      int result = db.SaveChanges();
    }


}
catch (DataException e)
{

}

第二种方法:

        var student= db.Students.Find(id);
        db.Students.student(item);
        db.SaveChanges();