An exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred

时间:2015-07-28 16:14:44

标签: c# asp.net-mvc entity-framework asp.net-web-api ef-code-first

I run into this error when I try to insert entries to my database. I can seed data manually but when I invoke the POST method in the Web API I get this error.

here's my user entity class:

    namespace YourTime.DataAccess.UserEntities
{
    [Table("Users")]
    public class UserProfile
    {
        [Key]
        public int UserId { get; set; }
        public string Activities { get; set; }
        public DateTime Birthday { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string FavoriteMusic { get; set; }
        public bool Verified { get; set; }
        public string Gender { get; set; }
        public string Email { get; set; }
        public DateTime UpdatedTime { get; set; }
        public string Hometown { get; set; }
        public virtual CoverPhoto Cover { get; set; }
        public virtual ICollection<Status> Statuses { get; set; }
        public virtual ICollection<Event> Events { get; set; }

    }
}

I'm using data access layer as an intermediate layer to fetch and update data. I have Repository class that is laid out like this:

    namespace YourTime.DataAccess.Repositories
{
    public abstract class Repository<T>: IRespository<T> where T : class
    {
        private readonly YourTimeProjectContext _context;

        protected Repository(YourTimeProjectContext context)
        {
            _context = context;
        }

        public virtual List<T> Get()
{
    return _context.Set<T>().ToList();
}

public  virtual T Get(int id)
{
    return _context.Set<T>().Find(id);
}

public virtual T Update(T obj)
{
    _context.Entry(obj).State = EntityState.Modified;
    _context.SaveChanges();
    return obj;
}

public virtual T Insert(T obj)
{
    _context.Set<T>().Add(obj);
    _context.SaveChanges();
    return obj;
}

public virtual int Delete(T obj)
{
    _context.Set<T>().Remove(obj);
    _context.SaveChanges();
    return _context.SaveChanges();
}

internal object Insert(object UserEntity)
{
    throw new System.NotImplementedException();
}
    }
}

Here's my model class

    namespace YourTime.Models
{
    public class UserModel
    {
        public int UserId { get; set; }
        public DateTime Birthday { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public bool Verified { get; set; }
        public string Gender { get; set; }
        public string Email { get; set; }
        public DateTime UpdatedTime { get; set; }
        public int StatusCount { get; set; }

    }

The Model factory class converts the entities to models back and forth. here's the code for the ModelFactory class

    namespace YourTime.DataAccess.Repositories
{
    public interface IModelFactory
    {
        UserModel Create(UserProfile user);

        UserProfile Create(UserModel userModel);

    }
    public class ModelFactory : IModelFactory
    {

        public UserModel Create(UserProfile user)
        {
            return new UserModel
            {
                FirstName = user.FirstName,
                Birthday = user.Birthday!=null? user.Birthday:DateTime.Now,
                Email = user.Email,
                Gender = user.Gender,
                UserId = user.UserId,
                LastName = user.LastName,
                StatusCount = user.Statuses!=null? user.Statuses.Count:0,
                UpdatedTime = user.UpdatedTime!=null? user.UpdatedTime:DateTime.Today,
                Verified = user.Verified!=null? user.Verified:true
            };
        }


        public UserProfile Create(UserModel user)
        {
            return new UserProfile
            {
                UserId = user.UserId,
                FirstName = user.FirstName,
                Email = user.Email,
                Gender = user.Gender,
                LastName = user.LastName
            };
        }
    }
}    

and finally here's my controller class for the API:

    namespace YourTime.Controllers
{
    public class UserController : ApiController{
    private IWebService _service;
        private IModelFactory _modelFactory;

        public UserController(  ) {
            _service = new WebService( );
            _modelFactory = new ModelFactory( );
        }

        public IHttpActionResult Get( ) {
            var users = _service.Users.Get( );
            var models = users.Select( _modelFactory.Create );

            return Ok( models );
        }

        public IHttpActionResult Get( int id ) {
            try {
                var user = _service.Users.Get( id );
                var model = _modelFactory.Create( user );

                return Ok( model );
            } catch ( Exception ex ) {
                //Logging
#if DEBUG
                return InternalServerError( ex );
#endif
                return InternalServerError( );
            }

        }

        public IHttpActionResult Post([FromBody]UserModel userModel ) {
            var userEntity = _modelFactory.Create( userModel );
            var user = _service.Users.Insert( userEntity );

            var model = _modelFactory.Create( user );
            return Created(string.Format("http://localhost:52962/api/user/{0}", model.UserId), model);
        }
    }
}

I encounter the error at '_context.SaveChanges()'. I'm passing in 3 parameters from the body, FirstName, LastName and UserId. Rest are set to default values. Any idea what may the problem?

Edit:

My seed code looks like this:

var status = new Status { Message = "Hello. This is a test", UpdateTime = DateTime.Now };
        var user1 = new UserProfile { FirstName = "Federica", LastName = "Fenu", Birthday = DateTime.Parse("9/10/1991"), UpdatedTime = DateTime.Now, Gender = "Male", Email = "gmujtaba_2005@hotmail.com", Statuses = new List<Status> { status } };
        var user2 = new UserProfile { FirstName = "Joe", LastName = "Goddard", Birthday = DateTime.Parse("9/10/1991"), UpdatedTime = DateTime.Now, Gender = "Male", Email = "gmujtaba_2005@yahoo.com", Statuses = new List<Status> { status } };
        context.UserProfiles.Add(user1);
        context.UserProfiles.Add(user2);

and here's the webservice class:

    namespace YourTime.DataAccess.Repositories
{
    public class WebService: IWebService
    {
        private Repository<UserProfile> _users;
        private Repository<Status> _statuses;
        private Repository<Video> _videos;
        private Repository<Event> _events;
        private Repository<CoverPhoto> _coverphotos;

        public Repository<UserProfile> Users
        {
            get
            {
                if (_users == null)
                    _users = new UserRepository(new YourTimeProjectContext());

                return _users;
            }
        }

        public Repository<Status> Statuses
        {
            get
            {
                if(_statuses==null)
                    _statuses = new StatusRepository(new YourTimeProjectContext());

                return _statuses;
            }

        }

        public Repository<Video> Videos
        {
            get
            {
                if(_videos==null)
                    _videos = new VideoRepository(new YourTimeProjectContext());

                return _videos;
            }
        }

        public Repository<Event> Events
        {
            get
            {
                if(_events==null)
                    _events = new EventRepository(new YourTimeProjectContext());

                return _events;
            }
        }

        public Repository<CoverPhoto> CoverPhotos
        {
            get
            {
                if(_coverphotos == null)
                    _coverphotos = new CoverPhotoRespository(new YourTimeProjectContext());

                return _coverphotos;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我在代码中发现了问题。我从正文传递的参数与User的Create函数中所需的参数不匹配。它需要以下值:

UserId = user.UserId,
FirstName = user.FirstName,
Email = user.Email,
Gender = user.Gender,
LastName = user.LastName

我只传递了FirstName,LastName和UserId。这就是为什么更改没有保存在dbContext中。