英孚核心 |需要使用导航 属性 来更新一个 属性,而不是另一个(模块)
EF Core | Need to use Navigation property for update on one property, but not another (Modules)
我有一个文件 table,我在其中将 FK 添加到模块 table 以添加它来自哪个模块。
当我们将记录创建到 FileSystemItems 中时,我们还需要更新 FileSystemItemsDatas。
我们用下面的代码来做到这一点:
public async Task<int> CreateFileSystemItem(FileSystemItemCreateDTO fileSystemItem)
{
if (fileSystemItem == null)
{
throw new ArgumentNullException(nameof(fileSystemItem));
}
var fileSystemItemToCreate = new FileSystemItems()
{
FileName = fileSystemItem.FileName,
FileType = fileSystemItem.FileType,
IsFolder = fileSystemItem.IsFolder,
LastWriteTime = fileSystemItem.LastWriteTime,
ParentId = fileSystemItem.ParentId,
FileMetadata = fileSystemItem.FileMetadata,
ModuleId = fileSystemItem.ModuleId,
};
fileSystemItemToCreate.FileSystemItemData.FileData = fileSystemItem.FileData;
BIContext.FileSystemItems.Add(fileSystemItemToCreate);
await SaveChangesAsync().ConfigureAwait(false);
return fileSystemItemToCreate.FileId;
}
然后我看到了这个错误:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'DisplayName', table 'Core.Modules'; column does not allow nulls. INSERT fails.
The statement has been terminated.
at System.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__180_0(Task`1 result)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
我知道我正在通过我的导航 属性 添加到 FileSytemItemsData,但是如何确保我不更新 .Modules 导航 属性,因为我不需要在这个案例.
FileSystemItems.cs
/// <summary>
/// File System Item
/// </summary>
public partial class FileSystemItems
{
/// <summary>
/// Initializes a new instance of the <see cref="FileSystemItems"/> class.
/// </summary>
public FileSystemItems()
{
ItemChildren = new HashSet<FileSystemItems>();
FileSystemItemData = new FileSystemItemDatas();
Module = new Modules();
}
/// <summary>
/// Gets or sets the file identifier.
/// </summary>
/// <value>
/// The file identifier.
/// </value>
public int FileId { get; set; }
/// <summary>
/// Gets or sets the parent identifier.
/// </summary>
/// <value>
/// The parent identifier.
/// </value>
public int? ParentId { get; set; }
/// <summary>
/// Gets or sets the name of the file.
/// </summary>
/// <value>
/// The name of the file.
/// </value>
public string FileName { get; set; }
/// <summary>
/// Gets or sets the type of the file.
/// </summary>
/// <value>
/// The type of the file.
/// </value>
public string FileType { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is folder.
/// </summary>
/// <value>
/// <c>true</c> if this instance is folder; otherwise, <c>false</c>.
/// </value>
public bool IsFolder { get; set; }
/// <summary>
/// Gets or sets the last write time.
/// </summary>
/// <value>
/// The last write time.
/// </value>
public DateTime LastWriteTime { get; set; }
/// <summary>
/// Gets or sets the file system item data identifier.
/// </summary>
/// <value>
/// The file system item data identifier.
/// </value>
public int? FileSystemItemDataId { get; set; }
/// <summary>
/// Gets or sets the module identifier.
/// </summary>
/// <value>
/// The module identifier.
/// </value>
public int? ModuleId { get; set; }
/// <summary>
/// Gets or sets the file metadata.
/// </summary>
/// <value>
/// The file metadata.
/// </value>
public string FileMetadata { get; set; }
/// <summary>
/// Gets or sets the file system item data.
/// </summary>
/// <value>
/// The file system item data.
/// </value>
public FileSystemItemDatas FileSystemItemData { get; set; }
/// <summary>
/// Gets or sets the item children.
/// </summary>
/// <value>
/// The item children.
/// </value>
public virtual ICollection<FileSystemItems> ItemChildren { get; set; }
/// <summary>
/// Gets or sets the parent item.
/// </summary>
/// <value>
/// The parent item.
/// </value>
public virtual FileSystemItems ParentItem { get; set; }
/// <summary>
/// Gets or sets the module.
/// </summary>
/// <value>
/// The module.
/// </value>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "It's a Module")]
public virtual Modules Module { get; set; }
}
Modules.cs
/// <summary>
/// Module
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "It's a Module")]
[Table("Modules", Schema = "Core")]
public partial class Modules
{
/// <summary>
/// Gets or sets the module identifier.
/// </summary>
/// <value>
/// The module identifier.
/// </value>
public int ModuleId { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>
/// The name.
/// </value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the display name.
/// </summary>
/// <value>
/// The name.
/// </value>
public string DisplayName { get; set; }
/// <summary>
/// Gets or sets the extension identifier.
/// </summary>
/// <value>
/// The extension identifier.
/// </value>
public int ExtensionId { get; set; }
/// <summary>
/// Gets or sets the file system items.
/// </summary>
/// <value>
/// The file system items.
/// </value>
public virtual ICollection<FileSystemItems> FileSystemItems { get; set; }
}
FileSystemItemsDatas.cs
/// <summary>
/// File system item data
/// </summary>
public partial class FileSystemItemDatas
{
/// <summary>
/// Initializes a new instance of the <see cref="FileSystemItemDatas"/> class.
/// </summary>
public FileSystemItemDatas()
{
FileSystemItems = new HashSet<FileSystemItems>();
}
/// <summary>
/// Gets or sets the file data identifier.
/// </summary>
/// <value>
/// The file data identifier.
/// </value>
public int FileDataId { get; set; }
#pragma warning disable CA1819 // Properties should not return arrays
/// <summary>
/// Gets or sets the file data.
/// </summary>
/// <value>
/// The file data.
/// </value>
public byte[] FileData { get; set; }
#pragma warning restore CA1819 // Properties should not return arrays
/// <summary>
/// Gets or sets the file system items.
/// </summary>
/// <value>
/// The file system items.
/// </value>
public ICollection<FileSystemItems> FileSystemItems { get; set; }
}
模型生成器代码:
modelBuilder.Entity<FileSystemItemDatas>(entity =>
{
entity.HasKey(e => e.FileDataId);
});
modelBuilder.Entity<FileSystemItems>(entity =>
{
entity.HasKey(e => e.FileId);
entity.Property(e => e.FileName)
.IsRequired()
.HasMaxLength(255)
.IsUnicode(false);
entity.Property(e => e.FileType)
.IsRequired()
.HasMaxLength(50)
.IsUnicode(false);
entity.Property(e => e.FileMetadata).IsRequired().HasColumnType("nvarchar(max)").HasDefaultValue("[{}]");
entity.Property(e => e.LastWriteTime).HasColumnType("datetime");
entity.HasOne(d => d.FileSystemItemData)
.WithMany(p => p.FileSystemItems)
.HasForeignKey(d => d.FileSystemItemDataId)
.HasConstraintName("FK_FileSystemItems_FileSystemItemDatas");
entity.HasOne(d => d.Module)
.WithMany(p => p.FileSystemItems)
.HasForeignKey(d => d.ModuleId)
.HasConstraintName("FK_FileSystemItems_ModuleId");
entity.HasOne(d => d.ParentItem)
.WithMany(p => p.ItemChildren)
.HasForeignKey(d => d.ParentId)
.HasConstraintName("FK_FileSystemItems_FileSystemItems");
entity.HasOne(d => d.ParentItem)
.WithMany(p => p.ItemChildren)
.HasForeignKey(d => d.ParentId)
.HasConstraintName("FK_FileSystemItems_FileSystemItems");
});
modelBuilder.Entity<Modules>(entity =>
{
entity.HasKey(e => e.ModuleId);
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(200)
.IsUnicode(false);
entity.Property(e => e.DisplayName)
.IsRequired()
.HasMaxLength(200)
.IsUnicode(false);
});
来自Progman
我不需要在 FileSystemItems 的构造函数中设置 Module 和 FileSystemItemData:
/// <summary>
/// Initializes a new instance of the <see cref="FileSystemItems"/> class.
/// </summary>
public FileSystemItems()
{
ItemChildren = new HashSet<FileSystemItems>();
}
我有一个文件 table,我在其中将 FK 添加到模块 table 以添加它来自哪个模块。
当我们将记录创建到 FileSystemItems 中时,我们还需要更新 FileSystemItemsDatas。
我们用下面的代码来做到这一点:
public async Task<int> CreateFileSystemItem(FileSystemItemCreateDTO fileSystemItem)
{
if (fileSystemItem == null)
{
throw new ArgumentNullException(nameof(fileSystemItem));
}
var fileSystemItemToCreate = new FileSystemItems()
{
FileName = fileSystemItem.FileName,
FileType = fileSystemItem.FileType,
IsFolder = fileSystemItem.IsFolder,
LastWriteTime = fileSystemItem.LastWriteTime,
ParentId = fileSystemItem.ParentId,
FileMetadata = fileSystemItem.FileMetadata,
ModuleId = fileSystemItem.ModuleId,
};
fileSystemItemToCreate.FileSystemItemData.FileData = fileSystemItem.FileData;
BIContext.FileSystemItems.Add(fileSystemItemToCreate);
await SaveChangesAsync().ConfigureAwait(false);
return fileSystemItemToCreate.FileId;
}
然后我看到了这个错误:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'DisplayName', table 'Core.Modules'; column does not allow nulls. INSERT fails.
The statement has been terminated.
at System.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__180_0(Task`1 result)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
我知道我正在通过我的导航 属性 添加到 FileSytemItemsData,但是如何确保我不更新 .Modules 导航 属性,因为我不需要在这个案例.
FileSystemItems.cs
/// <summary>
/// File System Item
/// </summary>
public partial class FileSystemItems
{
/// <summary>
/// Initializes a new instance of the <see cref="FileSystemItems"/> class.
/// </summary>
public FileSystemItems()
{
ItemChildren = new HashSet<FileSystemItems>();
FileSystemItemData = new FileSystemItemDatas();
Module = new Modules();
}
/// <summary>
/// Gets or sets the file identifier.
/// </summary>
/// <value>
/// The file identifier.
/// </value>
public int FileId { get; set; }
/// <summary>
/// Gets or sets the parent identifier.
/// </summary>
/// <value>
/// The parent identifier.
/// </value>
public int? ParentId { get; set; }
/// <summary>
/// Gets or sets the name of the file.
/// </summary>
/// <value>
/// The name of the file.
/// </value>
public string FileName { get; set; }
/// <summary>
/// Gets or sets the type of the file.
/// </summary>
/// <value>
/// The type of the file.
/// </value>
public string FileType { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is folder.
/// </summary>
/// <value>
/// <c>true</c> if this instance is folder; otherwise, <c>false</c>.
/// </value>
public bool IsFolder { get; set; }
/// <summary>
/// Gets or sets the last write time.
/// </summary>
/// <value>
/// The last write time.
/// </value>
public DateTime LastWriteTime { get; set; }
/// <summary>
/// Gets or sets the file system item data identifier.
/// </summary>
/// <value>
/// The file system item data identifier.
/// </value>
public int? FileSystemItemDataId { get; set; }
/// <summary>
/// Gets or sets the module identifier.
/// </summary>
/// <value>
/// The module identifier.
/// </value>
public int? ModuleId { get; set; }
/// <summary>
/// Gets or sets the file metadata.
/// </summary>
/// <value>
/// The file metadata.
/// </value>
public string FileMetadata { get; set; }
/// <summary>
/// Gets or sets the file system item data.
/// </summary>
/// <value>
/// The file system item data.
/// </value>
public FileSystemItemDatas FileSystemItemData { get; set; }
/// <summary>
/// Gets or sets the item children.
/// </summary>
/// <value>
/// The item children.
/// </value>
public virtual ICollection<FileSystemItems> ItemChildren { get; set; }
/// <summary>
/// Gets or sets the parent item.
/// </summary>
/// <value>
/// The parent item.
/// </value>
public virtual FileSystemItems ParentItem { get; set; }
/// <summary>
/// Gets or sets the module.
/// </summary>
/// <value>
/// The module.
/// </value>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "It's a Module")]
public virtual Modules Module { get; set; }
}
Modules.cs
/// <summary>
/// Module
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "It's a Module")]
[Table("Modules", Schema = "Core")]
public partial class Modules
{
/// <summary>
/// Gets or sets the module identifier.
/// </summary>
/// <value>
/// The module identifier.
/// </value>
public int ModuleId { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>
/// The name.
/// </value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the display name.
/// </summary>
/// <value>
/// The name.
/// </value>
public string DisplayName { get; set; }
/// <summary>
/// Gets or sets the extension identifier.
/// </summary>
/// <value>
/// The extension identifier.
/// </value>
public int ExtensionId { get; set; }
/// <summary>
/// Gets or sets the file system items.
/// </summary>
/// <value>
/// The file system items.
/// </value>
public virtual ICollection<FileSystemItems> FileSystemItems { get; set; }
}
FileSystemItemsDatas.cs
/// <summary>
/// File system item data
/// </summary>
public partial class FileSystemItemDatas
{
/// <summary>
/// Initializes a new instance of the <see cref="FileSystemItemDatas"/> class.
/// </summary>
public FileSystemItemDatas()
{
FileSystemItems = new HashSet<FileSystemItems>();
}
/// <summary>
/// Gets or sets the file data identifier.
/// </summary>
/// <value>
/// The file data identifier.
/// </value>
public int FileDataId { get; set; }
#pragma warning disable CA1819 // Properties should not return arrays
/// <summary>
/// Gets or sets the file data.
/// </summary>
/// <value>
/// The file data.
/// </value>
public byte[] FileData { get; set; }
#pragma warning restore CA1819 // Properties should not return arrays
/// <summary>
/// Gets or sets the file system items.
/// </summary>
/// <value>
/// The file system items.
/// </value>
public ICollection<FileSystemItems> FileSystemItems { get; set; }
}
模型生成器代码:
modelBuilder.Entity<FileSystemItemDatas>(entity =>
{
entity.HasKey(e => e.FileDataId);
});
modelBuilder.Entity<FileSystemItems>(entity =>
{
entity.HasKey(e => e.FileId);
entity.Property(e => e.FileName)
.IsRequired()
.HasMaxLength(255)
.IsUnicode(false);
entity.Property(e => e.FileType)
.IsRequired()
.HasMaxLength(50)
.IsUnicode(false);
entity.Property(e => e.FileMetadata).IsRequired().HasColumnType("nvarchar(max)").HasDefaultValue("[{}]");
entity.Property(e => e.LastWriteTime).HasColumnType("datetime");
entity.HasOne(d => d.FileSystemItemData)
.WithMany(p => p.FileSystemItems)
.HasForeignKey(d => d.FileSystemItemDataId)
.HasConstraintName("FK_FileSystemItems_FileSystemItemDatas");
entity.HasOne(d => d.Module)
.WithMany(p => p.FileSystemItems)
.HasForeignKey(d => d.ModuleId)
.HasConstraintName("FK_FileSystemItems_ModuleId");
entity.HasOne(d => d.ParentItem)
.WithMany(p => p.ItemChildren)
.HasForeignKey(d => d.ParentId)
.HasConstraintName("FK_FileSystemItems_FileSystemItems");
entity.HasOne(d => d.ParentItem)
.WithMany(p => p.ItemChildren)
.HasForeignKey(d => d.ParentId)
.HasConstraintName("FK_FileSystemItems_FileSystemItems");
});
modelBuilder.Entity<Modules>(entity =>
{
entity.HasKey(e => e.ModuleId);
entity.Property(e => e.Name)
.IsRequired()
.HasMaxLength(200)
.IsUnicode(false);
entity.Property(e => e.DisplayName)
.IsRequired()
.HasMaxLength(200)
.IsUnicode(false);
});
来自Progman
我不需要在 FileSystemItems 的构造函数中设置 Module 和 FileSystemItemData:
/// <summary>
/// Initializes a new instance of the <see cref="FileSystemItems"/> class.
/// </summary>
public FileSystemItems()
{
ItemChildren = new HashSet<FileSystemItems>();
}