当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - ASP.NET Entity Framework insert if not exists

问题描述:

Hey guys and girls :)

I'm currently trying to implement a c#/asp.net code-first entityframework database app (on azure) which would hold a list of movies. Every time i ask the app for a movie it does the following:

  1. query database
  2. if not found in database, query TMDB
  3. add to database (without duplicates)

i have a working query, i have a working TMDB parser, i can add things to the database. The problem arises when i try to have no duplicates in my relations.

My setup:

Movies

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

}

Genres

public partial class Genres

{

public Genres() { }

[Key]

public int Genre_ID { get; set; }

public string Genre_Name { get; set; }

}

Database Access Class

==> here is where my issues arise <==

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

and that's the (cleaned up) error message my ASP.NET WebAPI throws:

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,

网友答案:

First of all you need to add public virtual ICollection<Movies> Movies{ get; set; } to your Genres class to insure many to many relationship.

EDIT

Also I see that you have both db and dataBaseContext and this is wrong. You have to work with the same db context

I think something like that should work:

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();

        }
分享给朋友:
您可能感兴趣的文章:
随机阅读: