SQL Server & Entity Framework SaveChanges 时唯一约束异常
SQL Server & Entity Framework unique constraint exception when SaveChanges
我有这个数据:
当我将文件上传到 srv 时,有以下代码:
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 和下一个 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, MinimumLength = 1,
ErrorMessage = "Название расширения должно быть от 1 до 20 символов")]
public string displayname { get; set; }
[StringLength(200, MinimumLength = 1,
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, MinimumLength = 1,
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。
而且,您正在检查分机两次。为避免这种情况,您可以使用此 func
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; }
}
如果仍然无法正常工作,您可能需要重复数据库迁移
这是我的问题的答案
我不知道为什么,但只是出于某种原因才有效,有人可以解释一下吗?
只有储物柜可以帮助...
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;
}
我有这个数据:
当我将文件上传到 srv 时,有以下代码:
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 和下一个 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, MinimumLength = 1,
ErrorMessage = "Название расширения должно быть от 1 до 20 символов")]
public string displayname { get; set; }
[StringLength(200, MinimumLength = 1,
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, MinimumLength = 1,
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。 而且,您正在检查分机两次。为避免这种情况,您可以使用此 func
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; }
}
如果仍然无法正常工作,您可能需要重复数据库迁移
这是我的问题的答案
我不知道为什么,但只是出于某种原因才有效,有人可以解释一下吗? 只有储物柜可以帮助...
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;
}