我在SQL中有一个包含一个BLOB列的表。为了避免每次我想访问其他列时将此列加载到内存中,我已经完成了EF表拆分。这样,我有两个实体用于同一个表,BLOB只是在我想要访问它时才懒惰加载。所以要明确:这两个实体之间应该存在一对一的关系。 但是,当我更新非BLOB属性时,我得到了一些预期的验证错误,SoundFile是必需的并且不存在......但是如果我将其设置为不需要,则EF无法共享表... 一些代码如下所示:
[Table("Files")]
public class File
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
[StringLength(50, MinimumLength = 1)]
public string Name { get; set; }
[StringLength(300, MinimumLength = 0)]
public string Description { get; set; }
[JsonIgnore]
[Required]
public virtual SoundFile SoundFile { get; set; }
}
[Table("Files")]
public class SoundFile
{
[Key, ForeignKey("File")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Column("SoundFile")]
public byte[] Bytes { get; set; }
// Property is needed to tell EF that it's a one-to-one relationship
[JsonIgnore]
[Required]
public virtual File File { get; set; }
}
在那里可能会出现一些导致问题的错误,但是,当我改变某些东西时(比如说与必需的标签相关)它也不起作用,因为那时EF抱怨我不能让它们分享一个表...无论如何,当我尝试更新如下所示的文件名和/或描述时,我得到验证错误,因为SoundFile属性为null,因为我想避免从数据库加载它来进行这样一个简单的更新。变量value
是更新后的变量。
using (DataContext ctx = new DataContext())
{
ctx.Files.Attach(value);
var entry = ctx.Entry(value);
entry.Property(x => x.Name).IsModified = true;
entry.Property(x => x.Description).IsModified = true;
ctx.SaveChanges();
}
对此的任何想法都会很棒!在此先感谢:)
编辑当我尝试从数据库中删除文件记录时,再次使用File实体类,因为我不需要BLOB,我得到错误,我是缺少必需的属性。然而,不要求属性SoundFile
会破坏它,因为EF然后说:实体类型'SoundFile'和'File'不能共享表'Files',因为它们不在同一类型层次结构中或者没有有效的一对一外键关系,以及它们之间匹配的主键。
编辑2:根据请求,这是DataContext类的代码。这是基本的,因为我假设实体之间的关系是在其他类中捕获的。
public class DataContext : DbContext
{
public DataContext()
: base("name=DataContext")
{
}
public virtual DbSet<File> Files { get; set; }
}
编辑3:现在可以更新值。我必须在File和SoundFile中分别在其ID属性上设置[Key, ForeignKey("SoundFile")]
和[Key, ForeignKey("File")]
。这样,我可以删除File中SoundFile属性的Required属性,它将保持1对1的关系。但是,当我尝试删除数据库中的记录时,我仍然得到:“遇到无效数据。缺少必需的关系。检查StateEntries以确定约束违规的来源。” StateEntries不包含任何有用的东西......调试器无法看到它里面有什么。代码:
using (DataContext ctx = new DataContext())
{
var file = ctx.Files.Find(id);
ctx.Files.Remove(file);
ctx.SaveChanges(); // Throws here
}