If I understand your question you are asking how to add the actual file table as an entity so it can be exposed through the DbContext. First, create a model. My file table is named DocumentStore.
public class DocumentStore
{
public Guid stream_id { get; set; }
public Byte[]? file_stream { get; set; }
public string? name { get; set; }
[NotMapped]
public HierarchyId? path_locator { get; set; }
[NotMapped]
public HierarchyId? parent_path_locator { get; set; }
public string? file_type { get; set; }
public Int64 cached_file_size { get; set; }
public DateTimeOffset creation_time { get; set; }
public DateTimeOffset last_write_time { get; set; }
public DateTimeOffset last_access_time { get; set; }
public bool is_directory { get; set; }
public bool is_offline { get; set; }
public bool is_hidden { get; set; }
public bool is_readonly { get; set; }
public bool is_archive { get; set; }
public bool is_system { get; set; }
public bool is_temporary { get; set; }
}
You'll need to install a few NuGet packages. Visual Studio will help with this.
Add the entity to the DbContext.
public partial class ArchiveDbContext : DbContext
{
public ArchiveDbContext(DbContextOptions<ArchiveDbContext> options)
: base(options)
{
}
public DbSet<FileDescription>? FileDescriptions { get; set; }
public DbSet<DocumentStore> Documents { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<FileTableRoot>().HasNoKey().ToTable("FileTableRoot", t => t.ExcludeFromMigrations());
modelBuilder.Entity<FileDescription>().HasKey(m => m.Id);
modelBuilder.Entity<DocumentStore>().HasNoKey().ToTable("DocumentStore", t => t.ExcludeFromMigrations());
base.OnModelCreating(modelBuilder);
}
}
Add the a method to the IFileTableService; GetFileTableRecordByFileName(string name)
public interface IFileTableService
{
Task<string> GetFileTableDirectory(string fileStreamDirectory = "Archive");
Task<DocumentStore?> GetFileTableRecordByFileName(string name);
}
public class FileTableService : IFileTableService
{
private readonly ArchiveDbContext _context;
public FileTableService(ArchiveDbContext context)
{
_context = context;
}
public async Task<string> GetFileTableDirectory(string fileStreamDirectory = "Archive")
{
FileTableRoot? results = await _context.Set<FileTableRoot>()
.FromSqlRaw("SELECT FileTableRootPath() as Name").FirstOrDefaultAsync();
return $"{results?.Name}\\{fileStreamDirectory}";
}
public async Task<DocumentStore?> GetFileTableRecordByFileName(string name)
{
DocumentStore? doc = await _context.Documents.FirstOrDefaultAsync(d => d.name == name);
return doc;
}
}
invoke the GetFileTableRecordByFileName(string name) method.
[Route("api/[controller]")]
[ApiController]
public class FileTableController : ControllerBase
{
private readonly IFileTableService _fileTableService;
public FileTableController(IFileTableService fileTableService)
{
_fileTableService = fileTableService;
}
[HttpGet]
public async Task<IActionResult> GetAsync()
{
string directory = await _fileTableService.GetFileTableDirectory();
string[] files = Directory.GetFiles(directory).Select(f => Path.GetFileName(f)).ToArray();
return Ok(files);
}
[HttpGet("{filename}")]
public async Task<IActionResult> GetAsync(string filename)
{
string directory = await _fileTableService.GetFileTableDirectory("Archive");
string path = $"{directory}\\{filename}";
if(System.IO.File.Exists(path))
{
return File(System.IO.File.OpenRead(path), "application/octet-stream", filename);
}
return NotFound();
}
[HttpGet("Doc/{filename}")]
public async Task<IActionResult> GetDocAsync(string filename)
{
Models.DocumentStore? results = await _fileTableService.GetFileTableRecordByFileName(filename);
return Ok(results);
}
}
Again, this type of information is cover in the openly published Raw SQL Queries documentation.
However, I would not reference the file table directly. I would use a View, as suggested by Bruce, or a stored procedure.