使用 Entity Framework Core 将文件存储在数据库中

Posted

技术标签:

【中文标题】使用 Entity Framework Core 将文件存储在数据库中【英文标题】:Store files in database using Entity Framework Core 【发布时间】:2018-07-28 10:58:50 【问题描述】:

如何在 ASP.NET Core 应用程序中使用 Entity Framework Core(代码优先)将文件存储在 SQL Server 数据库中?

我尝试过使用Filestream,但不幸的是我收到了这个错误:

无法为实体类型“UserProfile”上的属性“Avatar”调用属性,因为它被配置为导航属性。属性只能用于配置标量属性

代码如下:

public class UserProfile : BaseEntity 
    public FileStream Avatar  get; set; 
    public string FirstName  get; set; 
    public string LastName  get; set; 
    public DateTime DateOfBirth  get; set; 
    public Sex Sex  get; set; 
    public string Address  get; set; 
    public string PhoneNumber  get; set; 

    public virtual IEnumerable<Email> Emails  get; set; 
    public virtual User User  get; set; 
    public int UserID  get; set; 

和映射:

public class UserProfileMap 
    public UserProfileMap(EntityTypeBuilder<UserProfile> entityBuilder) 
        entityBuilder.HasKey(e => e.ID);
        entityBuilder.Property(e => e.Avatar);
        entityBuilder.Property(e => e.FirstName);
        entityBuilder.Property(e => e.LastName);
        entityBuilder.Property(e => e.DateOfBirth);
        entityBuilder.Property(e => e.Sex);
        entityBuilder.Property(e => e.Address);
        entityBuilder.Property(e => e.PhoneNumber);
        entityBuilder.HasMany(e => e.Emails).WithOne(u => u.UserProfile).HasForeignKey(x => x.UserProfileID);
    

我该怎么办?谢谢!

【问题讨论】:

【参考方案1】:

您可以将文件字节转换为字节数组。

public byte[] Avatar  get; set; 

在 EF6 的类似方法中检查接受的答案: Save and retrieve image (binary) from SQL Server using Entity Framework 6

【讨论】:

但是有没有办法使用 Filestream 来存储它们? 实体类是简单的 POCO 类(普通的旧 CLR 对象)。支持的数据类型是基本的 .NET 数据类型(String、DateTime、Boolean、Byte、Byte[]、Int16、Int32、Int64、Single、Double、Decimal 和 System.Guid)。按照惯例,数据库提供程序根据属性的 CLR 类型选择数据类型。它还考虑了其​​他元数据,例如配置的最大长度、属性是否是主键的一部分等(参见docs.microsoft.com/en-us/ef/core/modeling/relational/data-types)。 IMO 我们不能使用 FileStream 作为属性类型。【参考方案2】:

我假设您正在尝试将 windows 文件流用于 sql server,即not yet supported by .NET Core。如前所述,您必须将文件存储为字节数组(它将在 sql server 中转换为 varbinary(max))并在使用内存流上传时复制文件内容。

【讨论】:

【参考方案3】:

通过 Ef core,您现在无法将文件存储在数据库中,因此您可以:

    将读取文件的结果存储为byte[] 像这样:
public byte[] Avatar  get; set; 
var avatar =  File.ReadAllBytes(filePath);

2.将您的机器用作文件服务器并将文件的路径存储在数据库中:

public string Avatar  get; set; 

在我看来,第二种方式更好,我总是使用这种模式,但这取决于您机器的 HDD 和您要存储的文件数量。

【讨论】:

以上是关于使用 Entity Framework Core 将文件存储在数据库中的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework Core 性能优化

在 Entity Framework Core 中使用 [ComplexType]

在 Entity Framework Core 中使用 SQL 视图

使用 Entity Framework Core 更新相关数据

使用 Entity Framework Core 自动增加部分主键

如何使用 Entity Framework Core 模拟异步存储库