【发布时间】:2016-01-19 18:46:33
【问题描述】:
当我尝试保存到我的数据库时出现错误
SqlException:当 IDENTITY_INSERT 设置为 OFF 时,无法在表“照片”中插入标识列的显式值。
我在 Visual Studio 2015 上使用 asp.net 5 MVC 6 和 EF 7 类似的问题还有很多。大多数都有 asp.net 5 MVC 6 或 EF 7 不支持的解决方案(有人说使用数据注释可以解决 EF 6 中的问题)。其他的都没有工作。我尽量不问,除非万不得已。
我的设计是每个用户会有很多文件夹,一个文件夹会有很多照片。
我将public ICollection<UserFolder> UserFolders { get; set; } 添加到ApplicationUser
模型:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations.Schema;
namespace FamPhotos.Models
{
public class UserFolder
{
public int ID { get; set; }
public string Name { get; set; }
public ICollection<Photo> Photo { get; set; }
public string ApplicationUserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
}
public class Photo
{
public int ID { get; set; }
public string Description { get; set; }
public DateTime UploadDate { get; set; }
public string Url { get; set; }
public int UserFolderId { get; set; }
public UserFolder UserFolder { get; set; }
}
}
控制器方法
// POST: Photos/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Photo photo, IFormFile files, int id)
{
if (files == null)
{
ModelState.AddModelError(string.Empty, "Please select a file to upload.");
}
else if (ModelState.IsValid)
{
photo.UploadDate = DateTime.Now;
photo.UserFolderId = id;
var folderName = _context.UserFolder.Where(q => q.ID == id).Single().Name;
//TODO: Check for image types
var fileName = photo.ID.ToString() + ContentDispositionHeaderValue.Parse(files.ContentDisposition).FileName.Trim('"');
var filePath = Path.Combine(_applicationEnvironment.ApplicationBasePath, "Photos", User.GetUserName(), folderName, fileName);
await files.SaveAsAsync(filePath);
photo.UserFolder = _context.UserFolder.Where(q => q.ID == id).Single();
photo.Url = "~/Photos/" + fileName;
_context.Add(photo);
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(photo);
}
观点:
@model FamPhotos.Models.Photo
@{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<form asp-action="Create" asp-controller="Photos" method="post" enctype="multipart/form-data">
<div class="form-horizontal">
<h4>Photo</h4>
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<input type="file" name="files" />
<label asp-for="Description" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger" />
</div>
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</form>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
}
我的 DbContext:
namespace FamPhotos.Models
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<UserFolder>()
.HasMany(q => q.Photo)
.WithOne(c => c.UserFolder)
.HasForeignKey(c => c.UserFolderId);
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
public DbSet<Photo> Photo { get; set; }
public DbSet<ApplicationUser> ApplicationUser { get; set; }
public DbSet<UserFolder> UserFolder { get; set; }
}
}
谢谢。
【问题讨论】:
-
您对错误感到困惑。 IDENTITY_INSERT OFF 表示数据库不允许您插入和标识值(这是当您有标识列时的正常情况)。在以下情况下,您可以打开 IDENTITY_INSERT,例如,恢复一堆包含身份键的记录,并且您希望在更新中覆盖键值或在插入中指定它。 ON 表示允许您插入身份。
-
您的 OnModelCreating 不完整。看看这个问题的公认答案。 stackoverflow.com/questions/15258571/…
标签: c# asp.net-mvc entity-framework visual-studio-2015