简体   繁体   中英

Using EF7 with raw queries without a model

I wonder if there is a way to use EF7 in fashion like Dapper without having a model generated from the database or otherwise generated. Something like

using(var context = new DbContext())
{
    string query = "...";
    var val = context.Database.ExecuteSqlCommand<RetVal>(query);
}

It looks like this is a well kept secret if there's a way. The idea here is to use EF7 as a thin wrapper over ADO.NET.

At this moment you cannot do that with EF core.

SQL queries can only be used to return entity types that are part of your model

You can see the limitations here : Raw SQL Queries Limitations

You can see the enhancement of it on EF Core backlog here : Support for ad hoc mapping of arbitrary types

Actually, I think what you are looking for can be done (in EF7 as well as in older versions of EF). You will need to use the Command object to execute the query for you, and then parse the results from the Command Reader.

here is an example:

using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using Microsoft.EntityFrameworkCore;

namespace IndexFragmentationExample
{
    public class IndexFragmentation
    {
        public string TableName { get; set; }
        public string IndexName { get; set; }
        public double FragmentationPercent { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new MyDbContext())
            {
                var indexFragmentations = GetIndexFragmentation(db);
                foreach (var indexFragmentation in indexFragmentations)
                {
                    Console.WriteLine("Table: " + indexFragmentation.TableName);
                    Console.WriteLine("Index: " + indexFragmentation.IndexName);
                    Console.WriteLine("Fragmentation: " + indexFragmentation.FragmentationPercent + "%");
                    Console.WriteLine();
                }
            }
        }

        private static List<IndexFragmentation> GetIndexFragmentation(DbContext db)
        {
            var fragmentations = new List<IndexFragmentation>();
            var connection = db.Database.GetDbConnection();
            connection.Open();
            using (var command = connection.CreateCommand())
            {
                command.CommandText = @"
                    SELECT 
                        OBJECT_NAME(ind.OBJECT_ID) AS TableName, 
                        ind.name AS IndexName, 
                        indexstats.avg_fragmentation_in_percent 
                    FROM 
                        sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, 'DETAILED') AS indexstats 
                    INNER JOIN 
                        sys.indexes AS ind 
                    ON 
                        ind.OBJECT_ID = indexstats.OBJECT_ID 
                        AND ind.index_id = indexstats.index_id";

                using (var reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        fragmentations.Add(new IndexFragmentation
                        {
                            TableName = reader["TableName"].ToString(),
                            IndexName = reader["IndexName"].ToString(),
                            FragmentationPercent = Convert.ToDouble(reader["avg_fragmentation_in_percent"])
                        });
                    }
                }
            }
            return fragmentations;
        }
    }

    public class MyDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=MyDb;Trusted_Connection=True;");
        }
    }
}

I hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM