我正在尝试构建一个ASP.NET应用程序,它应该有助于拼车。为此,我使用身份框架来管理帐户,并使用实体框架作为ORM。我的模型也使用了Identity的ApplicationDbContext,所以我在代码优先迁移方面不会有问题,因为我需要UserProfile对象和Identity的ApplicationUser之间的一对一关系。
以下是我的型号:
public class UserProfile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public string FirstName { get; set; }
public string Email { get; set; }
public string UserName { get; set; }
public virtual List<Trip> Trips { get; set; } = new List<Trip>();
public virtual List<Meeting> Meetings { get; set; } = new List<Meeting>();
}
public class Trip
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public virtual TripCheckpoint Departure { get; set; }
[Required]
public virtual TripCheckpoint Destination { get; set; }
[Required]
public int Seats { get; set; }
[NotMapped]
public int AvailableSeats => Seats - Passengers.Count;
[Required]
public virtual UserProfile Organizer { get; set; }
public double Price { get; set; } = 0.0;
public virtual List<UserProfile> Passengers { get; } = new List<UserProfile>();
public virtual DateTime Date { get; set; }
}
public class TripCheckpoint
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CheckPointId { get; set; }
[Required]
public string Place { get; set; }
[Required]
public TimeSpan Hour { get; set; }
}
public class Meeting
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime When { get; set; }
public string Where { get; set; }
}
这是我的ApplicationDbContext:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<UserProfile> Profiles { get; set; }
public DbSet<Trip> Trips { get; set; }
public DbSet<TripCheckpoint> Checkpoints { get; set; }
public DbSet<Meeting> Meetings { get; set; }
public ApplicationDbContext()
: base("helmoCars", throwIfV1Schema:false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
protected override void OnModelCreating(DbModelBuilder dbBuilder)
{
base.OnModelCreating(dbBuilder);
dbBuilder.Entity<ApplicationUser>().HasRequired(u => u.Profile).WithRequiredPrincipal().Map(m => m.MapKey("AppUser_Id"));
dbBuilder.Entity<Trip>().HasMany(t => t.Passengers).WithMany().Map(m =>
{
m.ToTable("Trip_Passengers");
m.MapLeftKey("Trip_Id");
m.MapRightKey("UserProfile_Id");
});
dbBuilder.Entity<Trip>().HasRequired(t => t.Organizer).WithMany(u => u.Trips).Map(m => m.MapKey("Trip_Organizer"))
.WillCascadeOnDelete(false);
dbBuilder.Entity<Trip>().HasRequired(t => t.Departure).WithRequiredDependent().Map(m => m.MapKey("Trip_Departure")).WillCascadeOnDelete(false);
dbBuilder.Entity<Trip>().HasRequired(t => t.Destination).WithRequiredDependent().Map(m => m.MapKey("Trip_Destination")).WillCascadeOnDelete(false);
}
}
这就是我如何使用ApplicationDbContext:
public class TripRepository
{
private ApplicationDbContext _db;
public TripRepository(ApplicationDbContext context)
{
this._db = context;
}
public void AddTrips(List<Trip> trips)
{
_db.Database.Log = message => Debug.Write(message);
_db.Trips.AddRange(trips);
_db.SaveChanges();
}
}
我这样使用我的TripRepository:
ApplicationDbContext context = HttpContext.GetOwinContext().Get<ApplicationDbContext>();
var tr = new TripRepository(context);
tr.AddTrips(trips); // trips is a valid List<Trip>
ApplicationDbContext的SaveChanges((方法每次调用时都会抛出一个System.Data.Entity.Core.UpdateException,即使我确定添加到DbSet的trips是有效的List,我也会使用调试器进行检查。例外是我唯一的反馈,所以我真的不知道我做错了什么。。有什么想法吗?
这是我在调试输出窗口中得到的唯一反馈:
Exception levée : 'System.Data.Entity.Core.UpdateException' dans
EntityFramework.dll
Exception levée : 'System.Data.Entity.Core.UpdateException' dans
EntityFramework.SqlServer.dll
Exception levée : 'System.Data.Entity.Infrastructure.DbUpdateException' dans
EntityFramework.dll
Exception levée : 'System.Data.Entity.Infrastructure.DbUpdateException' dans
System.Web.Mvc.dll
Exception levée : 'System.Data.Entity.Infrastructure.DbUpdateException' dans
System.Web.Mvc.dll
这就是我如何填写之后给AddTrips方法的列表(其中trip是我从表单中获得的视图模型(:
trips.Add(new Trip()
{
Date = trip.Date,
Price = trip.Price,
Seats = trip.Seats,
Organizer = user,
Departure = new TripCheckpoint() { Place = trip.DeparturePlace, Hour = trip.DepartureHour.TimeOfDay },
Destination = new TripCheckpoint() { Place = trip.DestinationPlace, Hour = trip.DestinationHour.TimeOfDay }
});
我在视图中发现了更好的日志(我使用的是AJAX(。对于其他有问题的人,如果你想要更好的日志来发现错误,可以用html表单进行尝试,并在它工作后将其转换为ajax表单。