【问题标题】:ASP.NET Entity Framework insert if not existsASP.NET Entity Framework 插入(如果不存在)
【发布时间】:2014-12-01 13:06:41
【问题描述】:

大家好:)

我目前正在尝试实现一个 c#/asp.net 代码优先实体框架数据库应用程序(在 azure 上),它可以保存电影列表。每次我向应用询问电影时,它都会执行以下操作:

  1. 查询数据库
  2. 如果在数据库中没有找到,查询TMDB
  3. 添加到数据库(不重复)

我有一个有效的查询,我有一个有效的 TMDB 解析器,我可以将内容添加到数据库中。当我试图在我的关系中没有重复时,就会出现问题。

我的设置:

电影

public partial class Movies
    {
        public Movies() { this.Genres = new HashSet<Genres>(); /* [...] */ }

        [Key]
        public int Movie_ID { get; set; }
        // [...]
        public virtual ICollection<Genres> Genres { get; set; }
    }

类型

public partial class Genres
{
    public Genres() { }

    [Key]
    public int Genre_ID { get; set; }
    public string Genre_Name { get; set; }
}

数据库访问类

==> 这是我的问题出现的地方

Movies daMov = new Movies();
// [...]
foreach ( string genre in movieGenres )
        {
            Genres daGenre = await dataBaseContext.Genres.Where(
                        m =>
                            m.Genre_Name == genre
                        ).FirstOrDefaultAsync( );       // query genre from db

            // doesn't exist - firstOrDefault() returns default
            if ( daGenre == null || object.Equals( daGenre, default( Genres ) ) )               
            {
                daGenre = new Genres(); // create new in db
                daGenre.Genre_Name = genre;
                daMov.Genres.Add( daGenre ); // works fine, just that it creates a new genre
            }
            else
            {
                // here i've been googling around for some time and found the following 
                // (all with the same error)

                //db.Genres.Attach( daGenre ); // don't create new??
                //daMov.Genres.Add( daGenre ); // should work?
                //db.Entry( daGenre ).State = EntityState.Modified; // no it doesn't
            }
        }
// [...]
db.Movies.Add( daMov );
await db.SaveChangesAsync(); // DBHelper.cs:line 140

这就是我的 ASP.NET WebAPI 抛出的(清理后的)错误消息:

ExceptionMessage: 
An error occurred while saving entities that do not expose foreign key properties for their relationships. 
The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. 
Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.,
ExceptionType: System.Data.Entity.Infrastructure.DbUpdateException,

StackTrace:    
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at dotNETproject1.WebAPI.App_Code.DBHelper.<queryIMDB>d__0.MoveNext() in App_Code\DBHelper.cs: line 140

InnerException: 
    ExceptionMessage: 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.,
    ExceptionType: System.Data.Entity.Core.OptimisticConcurrencyException,

【问题讨论】:

  • Copyright © 1990-2014 IMDb.com, Inc....您是否有他们的书面许可来抓取他们的网站?在那之前,你可能只是在浪费你的时间[好吧,直到他们决定无论如何都阻止你的刮板]:)

标签: c# asp.net sql-server entity-framework azure


【解决方案1】:

首先,您需要将 public virtual ICollection&lt;Movies&gt; Movies{ get; set; } 添加到您的 Genres 类以确保多对多关系。

编辑

我还看到您同时拥有dbdataBaseContext,这是错误的。 您必须使用相同的数据库上下文

我认为这样的事情应该可行:

Movies daMov = new Movies();
// [...]
foreach ( string genre in movieGenres )
        {
            Genres daGenre = await db.Genres.FirstOrDefaultAsync(
                   m => m.Genre_Name == genre);

            // doesn't exist - firstOrDefault() returns default
            if ( daGenre == null || object.Equals(daGenre, default(Genres)))               
            {
                daGenre = new Genres(); // create new in db
                daGenre.Genre_Name = genre;
            }
            daMov.Genres.Add( daGenre );
            db.Movies.Add(daMov);
            await db.SaveChangesAsync();

        }

【讨论】:

  • 不完全 :( ExceptionMessage:“检测到类型为 'dotNETproject1.WebAPI.Movies' 的自引用循环。路径 'Genres[0].Movies'。”
  • Asmodiel,您还在处理循环问题吗?你什么时候得到那个错误? .Net 比序列化器更宽容关系循环。如果您正在执行 Json 或 Javascript 序列化,则可以使用 [ScriptIgnore] 或 [JsonIgnore] 装饰属性。
  • 这不是插入如果不存在行为。这是选择和插入行为。它不适用于高并发环境。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多