如何解决SaveChanges 时 SQL Server 和实体框架唯一约束异常
我有这个数据:
DataContext db = new DataContext();
[HttpPost]
public ActionResult UploadFiles(HttpPostedFileBase[] files,int? folderid,string description)
{
foreach (HttpPostedFileBase file in files)
{
if (file != null)
{
string fileName = Path.GetFileNameWithoutExtension(file.FileName);
string fileExt = Path.GetExtension(file.FileName)?.Remove(0,1);
int? extensionid = db.FileExtensions.FirstOrDefault(m => m.displayname == fileExt)
?.file_extensionid;
if (extensionid == null)
{
CreateExtension(fileExt,out int? extid);
extensionid = extid;
}
if (CheckFileExist(fileName,fileExt,folderid))
{
fileName = fileName + $" ({DateTime.Now.ToString("dd-MM-yy HH:mm:ss")})";
}
File dbFile = new File();
dbFile.folderid = folderid;
dbFile.displayname = fileName;
dbFile.file_extensionid = extensionid;
dbFile.file_content = GetFileBytes(file);
dbFile.description = description;
db.Files.Add(dbFile);
db.SaveChanges();
}
}
return RedirectToAction("Partial_SuccesuploadedToast","Toast");
}
如果 FileExtension 还没有在数据库中,我想用这个方法创建它:
private void CreateExtension(string name,out int? extid)
{
if (db.FileExtensions.Any(m => m.displayname == name))
{
extid = db.FileExtensions.FirstOrDefault(m => m.displayname == name)?.file_extensionid;
return;
}
FileExtension fileExtension = new FileExtension()
{
displayname = name
};
db.FileExtensions.Add(fileExtension);
extid = fileExtension.file_extensionid;
db.SaveChanges();
}
所以,当我上传一些带有一个扩展名的文件时,我得到一个例外,即无法添加具有新文件 ext 的实体,因为已经有(唯一约束)。 我能用它做什么?我保存 EXT 和下一个 foreach 循环迭代必须检查 EXT 是否已经存在,idk ...请帮忙!
上下文类:
public class File
{
[Key]
[HiddenInput(displayValue = false)]
public int fileid { get; set; }
[required(ErrorMessage = "Обязательно укажите название!")]
[StringLength(200,MinimumLength = 1,ErrorMessage = "Название файла должно быть от 1 до 200 символов")]
public string displayname { get; set; }
[StringLength(1000,ErrorMessage = "Описание файла должно до 1000 символов")]
public string description { get; set; }
[HiddenInput(displayValue = false)]
public int? file_extensionid { get; set; }
[HiddenInput(displayValue = false)]
public int? folderid { get; set; }
public byte[] file_content { get; set; }
[ForeignKey("file_extensionid")]
public FileExtension FileExtension { get; set; }
[ForeignKey("folderid")]
public Folder Folder { get; set; }
}
public class FileExtension
{
[Key]
[HiddenInput(displayValue = false)]
public int file_extensionid { get; set; }
[required(ErrorMessage = "Обязательно укажите название расширения!")]
[StringLength(20,ErrorMessage = "Название расширения должно быть от 1 до 20 символов")]
public string displayname { get; set; }
[StringLength(200,ErrorMessage = "Название иконки должно быть от 1 до 200 символов")]
public string icon_filename { get; set; }
}
public class Folder
{
[Key]
[HiddenInput(displayValue = false)]
public int folderid { get; set; } = 0;
[required(ErrorMessage = "Обязательно укажите название!")]
[StringLength(100,ErrorMessage = "Название папки должно быть от 1 до 100 символов")]
public string displayname { get; set; }
[HiddenInput(displayValue = false)]
public int? parent_folderid { get; set; }
//
[ForeignKey("parent_folderid")]
public Folder ParentFolder { get; set; }
}
解决方法
你有一个错误。您正在尝试在保存更改之前获取扩展 ID。 而且,您正在检查扩展名两次。为了避免这种情况,您可以使用此功能
private int? GetExtensionId(string name)
{
var extItem= db.FileExtensions.FirstOrDefault(m => m.displayname == name);
if(extItem!=null) return extItem.file_extensionid;
var fileExtension = new FileExtension()
{
displayname = name
};
db.FileExtensions.Add(fileExtension);
db.SaveChanges();
return fileExtension.file_extensionid;
}
并替换
int? extensionid = db.FileExtensions.FirstOrDefault(m => m.displayname == fileExt)
?.file_extensionid;
if (extensionid == null)
{
CreateExtension(fileExt,out int? extid);
extensionid = extid;
}
有了这个
var extensionid = GetExtensionId(fileExt);
也可以尝试在file和fileext之间添加一对多的关系
public class File
{
.....
[HiddenInput(DisplayValue = false)]
public int? file_extensionid { get; set; }
[ForeignKey(nameof(file_extensionid))]
[InverseProperty("Files")]
public FileExtension FileExtension { get; set; }
public class FileExtension
{
.....
[InverseProperty(nameof(File.FileExtension))]
public virtual ICollection<File> Files { get; set; }
}
如果它仍然不起作用,您可能需要重复数据库迁移
,这是我问题的答案link
我不知道为什么,但只是出于某种原因才有效,有人可以解释一下吗? 只有储物柜可以帮助...
private static object locker = new object();
private int? GetExtensionId(string name)
{
int? result = null;
lock (locker)
{
var extItem = db.FileExtensions.FirstOrDefault(m => m.displayname == name);
if (extItem != null) return extItem.file_extensionid;
var fileExtension = new FileExtension()
{
displayname = name
};
db.FileExtensions.Add(fileExtension);
db.SaveChanges();
result = fileExtension.file_extensionid;
}
return result;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。