Search code examples
asp.netsql-serverasp.net-coreef-code-firstrepository-pattern

How to call Db view file in repository pattern?


I am creating a view file in SQL Server as shown in the image below.

enter image description here

and I created a model to get results from this view:

public class FactALLCousumption : BaseEntity, IAggregateRoot
{

    public double sumActiveImportTotal { get;  set; }
    public DateTime hour { get;  set; }
    public int fullDateAlternateKey { get;  set; }
}

But I can't call this view in my repository. My repository code is bellow:

public class FactCousumptionRepository: GenericRepository<FactCousumption>, IFactCousumptionRepository
{
    public DbContext _dbContext;

    public FactCousumptionRepository(BaseDbContext context) : base(context)
    {
        _dbContext = context;           
    }

    public async Task<FactALLCousumption> GetTotalAllCousumption()
    {

    }
}

Solution

  • In EF Core 2.2 or 2.1, you could use Query types.

    According to the screenshot and the model to be used for the View you provided , I make a simple working demo like below , you could refer to and make the modification as per your demand:

    1.Model

     public class FactCousumption
    {
        public int Id { get; set; }
        public double SumActiveImportTotal { get; set; }
        public int DateKeyId { get; set; }
        [ForeignKey("DateKeyId")]
        public Dim_Date Dim_Date { get; set; }
        public int TimeAltKeyId { get; set; }
        [ForeignKey("TimeAltKeyId")]
        public Dim_Time Dim_Time { get; set; }
        public int TariffKeyId { get; set; }
        [ForeignKey("TariffKeyId")]
        public Dim_Tariff Dim_Tariff { get; set; }
    }
    
    public class Dim_Date
    {
        [Key]
        public int DateKey { get; set; }
        public int FullDateAlternateKey { get; set; }
        public DateTime Date { get; set; }
        public ICollection<FactCousumption> FactCousumptions { get; set; }
    }
    
    public class Dim_Time
    {
        [Key]
        public int TimeAltKey { get; set; }
        public DateTime Hour { get; set; }
        public ICollection<FactCousumption> FactCousumptions { get; set; }
    }
     public class Dim_Tariff
    {
        [Key]
        public int TariffType { get; set; }
        public string TariffName { get; set; }
    
        public ICollection<FactCousumption> FactCousumptions { get; set; }
    }
    

    2.Create SQL View

    CREATE VIEW [dbo].[View1]
    AS  SELECT SUM(FactCousumption.SumActiveImportTotal) AS consumption ,Dim_Time.HOUR,Dim_Date.FullDateAlternateKey,Dim_Tariff.TariffName
      FROM FactCousumption INNER JOIN
            Dim_Date ON FactCousumption.DateKeyId = Dim_Date.DateKey INNER JOIN
            Dim_Time ON FactCousumption.TimeAltKeyId=Dim_Time.TimeAltKey INNER JOIN
            Dim_Tariff ON FactCousumption.TariffKeyId=Dim_Tariff.TariffType
      GROUP BY Dim_Date.FullDateAlternateKey, Dim_Time.HOUR ,Dim_Tariff.TariffName
    

    3.The model that is used for the view , note : the property name in model should be consistent with those in the view

    public class FactALLCousumption
    {
        public double consumption { get; set; }
        public DateTime hour { get; set; }
        public int fullDateAlternateKey { get; set; }
    }
    

    4.DbContext , create a DbQuery property in my DbContext to consume the view results inside the Model and set up the View especially if you have different view name than your Class.

     public DbQuery<FactALLCousumption> FactALLCousumption { get; set; }
    
     protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
            base.OnModelCreating(modelBuilder);
    
            modelBuilder.Query<FactALLCousumption>().ToView("View1");
     }
    

    5.Finally you can easily get the results of the View like this.

    public async Task<FactALLCousumption> GetTotalAllCousumption()
    {
            var result = await _context.FactALLCousumption.FirstOrDefaultAsync();
    
            return result;
    }
    

    Note: It's worth noting that DbQuery won't be/is not supported anymore in EF Core 3.0. See here