Consulta SQL bruta sem DbSet - Entity Framework Core


107

Com a remoção do Entity Framework Core, dbData.Database.SqlQuery<SomeModel>não consigo encontrar uma solução para construir uma consulta SQL bruta para minha consulta de pesquisa de texto completo que retornará os dados das tabelas e também a classificação.

O único método que vi para construir uma consulta SQL bruta no Entity Framework Core é por meio do dbData.Product.FromSql("SQL SCRIPT");qual não é útil, pois não tenho um DbSet que mapeie a classificação retornada na consulta.

Alguma ideia???


15
Sentirei muita falta do SqlQuery <T> e não quero ter que mapear classes personalizadas para meu DbContext quando eu realmente preciso de um DTO simples para um caso de uso específico. Eu criei uma voz do usuário para solicitar a adição desse recurso de volta ao EF Core, que todos podem votar se quiserem que esse recurso de volta: data.uservoice.com/forums/…
Matt Sanders

1
De acordo com github.com/aspnet/EntityFramework/issues/1862 , isso agora é direcionado para EF core 1.2 e / ou 1.1.0-preview1
Dan Field

2
Com base no que @Devon acabou de dizer, passei muito tempo descobrindo que eles são métodos de extensão em Microsoft.EntityFrameworkCore.SqlServer. Você precisará adicionar isso ao seu projeto antes de obter esses métodos de extensão.
Daniel

3
Suspiro, isso parece algum tipo de decisão de um astronauta da arquitetura: "as pessoas não deveriam querer isso". Acho que tenho que instalar o Dapper apenas para este caso. Irritante.
Dirk Boer

1
@MattSanders - seu link de usuário parece estar morto nesse meio tempo. Você sabe para onde foi?
Dirk Boer

Respostas:


127

Depende se você está usando EF Core 2.1 ou EF Core 3 e versões superiores .

Se você estiver usando EF Core 2.1

Se estiver usando o EF Core 2.1 Release Candidate 1 disponível desde 7 de maio de 2018, você pode aproveitar as vantagens do novo recurso proposto, que é o tipo de consulta.

Qual é o tipo de consulta ?

Além dos tipos de entidade, um modelo EF Core pode conter tipos de consulta, que podem ser usados ​​para realizar consultas de banco de dados contra dados que não estão mapeados para tipos de entidade.

Quando usar o tipo de consulta?

Servindo como o tipo de retorno para consultas ad hoc FromSql ().

Mapeamento para visualizações de banco de dados.

Mapeamento para tabelas que não possuem uma chave primária definida.

Mapeamento para consultas definidas no modelo.

Assim, você não precisa mais fazer todos os hacks ou soluções alternativas propostas como respostas à sua pergunta. Basta seguir estas etapas:

Primeiro você definiu uma nova propriedade de tipo DbQuery<T>onde Té o tipo da classe que carregará os valores da coluna de sua consulta SQL. Então, em seu DbContextvocê terá isto:

public DbQuery<SomeModel> SomeModels { get; set; }

Em segundo lugar, use o FromSqlmétodo como você faz com DbSet<T>:

var result = context.SomeModels.FromSql("SQL_SCRIPT").ToList();
var result = await context.SomeModels.FromSql("SQL_SCRIPT").ToListAsync();

Observe também que DdContexts são classes parciais , portanto, você pode criar um ou mais arquivos separados para organizar suas definições 'DbQuery SQL bruto' da maneira que melhor lhe convier.


Se você estiver usando EF Core 3.0 e versões superiores

O tipo de consulta agora é conhecido como tipo de entidade sem chave . Como dito acima, os tipos de consulta foram introduzidos no EF Core 2.1. Se você estiver usando EF Core 3.0 ou versão superior, você deve agora considerar o uso de tipos de tntity sem chave porque os tipos de consulta agora estão marcados como obsoletos.

Este recurso foi adicionado ao EF Core 2.1 com o nome de tipos de consulta. No EF Core 3.0, o conceito foi renomeado para tipos de entidade sem chave. A anotação de dados [sem chave] tornou-se disponível no EFCore 5.0.

Ainda temos os mesmos cenários dos tipos de consulta para quando usar o tipo de entidade sem chave.

Então, para usá-lo, você precisa primeiro marcar sua classe SomeModelcom [Keyless]anotação de dados ou por meio de configuração fluente com .HasNoKey()chamada de método como abaixo:

public DbSet<SomeModel> SomeModels { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<SomeModel>().HasNoKey();
}

Após essa configuração, você pode usar um dos métodos explicados aqui para executar sua consulta SQL. Por exemplo, você pode usar este:

var result = context.SomeModels.FromSqlRaw("SQL SCRIPT").ToList();

18
Esta resposta deve ser a melhor solução ao usar EF Core 2.1 e superior. 👍
Will Huang

2
@CodeNotFound E se eu não precisar do resultado ou se for um tipo primitivo (por exemplo bit)?
Shimmy Weitzhandler

5
Usando CodeFirst, isso criou automaticamente uma tabela com todas essas propriedades, adicionar [NotMapped]à SomeModelsclasse não funciona para mim. Eu perdi alguma coisa?
Jean-Paul de

7
O EF Core 3.0 substitui o DbQueryuso apenas DbSetcom tipos de entidade sem chave .
NetMage

3
Apenas para sua informação, devido a algum bug no EF core 3.0, uma migração de código ainda tentará criar uma tabela mesmo em entidades marcadas com HasNoKey (). Portanto, você também deve adicionar .ToView (null). Por exemplo, modelBuilder.Entity<MyData>().HasNoKey().ToView(null);@ Jean-Paul, acho que isso resolve seu problema
stann1

36

Com base nas outras respostas, escrevi este auxiliar que realiza a tarefa, incluindo exemplo de uso:

public static class Helper
{
    public static List<T> RawSqlQuery<T>(string query, Func<DbDataReader, T> map)
    {
        using (var context = new DbContext())
        {
            using (var command = context.Database.GetDbConnection().CreateCommand())
            {
                command.CommandText = query;
                command.CommandType = CommandType.Text;

                context.Database.OpenConnection();

                using (var result = command.ExecuteReader())
                {
                    var entities = new List<T>();

                    while (result.Read())
                    {
                        entities.Add(map(result));
                    }

                    return entities;
                }
            }
        }
    }

Uso:

public class TopUser
{
    public string Name { get; set; }

    public int Count { get; set; }
}

var result = Helper.RawSqlQuery(
    "SELECT TOP 10 Name, COUNT(*) FROM Users U"
    + " INNER JOIN Signups S ON U.UserId = S.UserId"
    + " GROUP BY U.Name ORDER BY COUNT(*) DESC",
    x => new TopUser { Name = (string)x[0], Count = (int)x[1] });

result.ForEach(x => Console.WriteLine($"{x.Name,-25}{x.Count}"));

Eu pretendo me livrar dele assim que o suporte integrado for adicionado. De acordo com uma declaração de Arthur Vickers da equipe EF Core, é uma alta prioridade para o pós 2.0. O problema está sendo rastreado aqui .


boa resposta, gostei.
setembro de

31

No EF Core você não pode mais executar sql bruto "livre". Você deve definir uma classe POCO e um DbSetpara essa classe. No seu caso, você precisará definir a Classificação :

var ranks = DbContext.Ranks
   .FromSql("SQL_SCRIPT OR STORED_PROCEDURE @p0,@p1,...etc", parameters)
   .AsNoTracking().ToList();

Como certamente será somente leitura, será útil incluir a .AsNoTracking()chamada.

EDIT - Quebrando a mudança no EF Core 3.0:

DbQuery () agora está obsoleto, ao invés DbSet () deve ser usado (novamente). Se você tiver uma entidade sem chave, ou seja, não requer chave primária, você pode usar o método HasNoKey () :

ModelBuilder.Entity<SomeModel>().HasNoKey()

Mais informações podem ser encontradas aqui


3
Portanto, acho que também terei de estender o DbContextpara incluir uma nova propriedade DbSet<Rank> Rank { get; set; }. Que implicações isso terá agora em referência ao linq? Ou seja, não poderemos agora usar uma instrução como DBContext.Rank.Where(i => i.key == 1)e essa instrução não terá implementação em SQL e, portanto, falhará?
David Harlow

O Linq emitido contra este conjunto deve ser resolvido na memória. Se você precisa emitir uma cláusula WHERE sql diferente, você deve incluí-los como parâmetros ou construir um script diferente.
E-Bat

Meu DbSet não tem um método "FromSql". Esta é uma extensão que estou perdendo?
birwin

1
@birwin, você precisa importar o namespace Microsoft.EntityFrameworkCore
E-Bat

20

Você pode executar sql bruto no EF Core - Adicione esta classe ao seu projeto. Isso permitirá que você execute o SQL bruto e obtenha os resultados básicos sem ter que definir um POCO e um DBSet. Consulte https://github.com/aspnet/EntityFramework/issues/1862#issuecomment-220787464 para obter o exemplo original.

using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.EntityFrameworkCore
{
    public static class RDFacadeExtensions
    {
        public static RelationalDataReader ExecuteSqlQuery(this DatabaseFacade databaseFacade, string sql, params object[] parameters)
        {
            var concurrencyDetector = databaseFacade.GetService<IConcurrencyDetector>();

            using (concurrencyDetector.EnterCriticalSection())
            {
                var rawSqlCommand = databaseFacade
                    .GetService<IRawSqlCommandBuilder>()
                    .Build(sql, parameters);

                return rawSqlCommand
                    .RelationalCommand
                    .ExecuteReader(
                        databaseFacade.GetService<IRelationalConnection>(),
                        parameterValues: rawSqlCommand.ParameterValues);
            }
        }

        public static async Task<RelationalDataReader> ExecuteSqlQueryAsync(this DatabaseFacade databaseFacade, 
                                                             string sql, 
                                                             CancellationToken cancellationToken = default(CancellationToken),
                                                             params object[] parameters)
        {

            var concurrencyDetector = databaseFacade.GetService<IConcurrencyDetector>();

            using (concurrencyDetector.EnterCriticalSection())
            {
                var rawSqlCommand = databaseFacade
                    .GetService<IRawSqlCommandBuilder>()
                    .Build(sql, parameters);

                return await rawSqlCommand
                    .RelationalCommand
                    .ExecuteReaderAsync(
                        databaseFacade.GetService<IRelationalConnection>(),
                        parameterValues: rawSqlCommand.ParameterValues,
                        cancellationToken: cancellationToken);
            }
        }
    }
}

Aqui está um exemplo de como usá-lo:

// Execute a query.
using(var dr = await db.Database.ExecuteSqlQueryAsync("SELECT ID, Credits, LoginDate FROM SamplePlayer WHERE " +
                                                          "Name IN ('Electro', 'Nitro')"))
{
    // Output rows.
    var reader = dr.DbDataReader;
    while (reader.Read())
    {
        Console.Write("{0}\t{1}\t{2} \n", reader[0], reader[1], reader[2]);
    }
}

18

Por enquanto, até que haja algo novo da EFCore, eu usaria um comando e mapearia manualmente

  using (var command = this.DbContext.Database.GetDbConnection().CreateCommand())
  {
      command.CommandText = "SELECT ... WHERE ...> @p1)";
      command.CommandType = CommandType.Text;
      var parameter = new SqlParameter("@p1",...);
      command.Parameters.Add(parameter);

      this.DbContext.Database.OpenConnection();

      using (var result = command.ExecuteReader())
      {
         while (result.Read())
         {
            .... // Map to your entity
         }
      }
  }

Tente SqlParameter para evitar injeção Sql.

 dbData.Product.FromSql("SQL SCRIPT");

FromSql não funciona com consulta completa. Exemplo, se você quiser incluir uma cláusula WHERE, ela será ignorada.

Alguns links:

Execução de consultas SQL brutas usando Entity Framework Core

Consultas SQL brutas


7

No Core 2.1, você pode fazer algo assim:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
       modelBuilder.Query<Ranks>();
}

e definir o seu procedimento SQL, como:

public async Task<List<Ranks>> GetRanks(string value1, Nullable<decimal> value2)
{
    SqlParameter value1Input = new SqlParameter("@Param1", value1?? (object)DBNull.Value);
    SqlParameter value2Input = new SqlParameter("@Param2", value2?? (object)DBNull.Value);

    List<Ranks> getRanks = await this.Query<Ranks>().FromSql("STORED_PROCEDURE @Param1, @Param2", value1Input, value2Input).ToListAsync();

    return getRanks;
}

Desta forma, o modelo de Ranks não será criado em seu BD.

Agora, em seu controlador / ação, você pode chamar:

List<Ranks> gettingRanks = _DbContext.GetRanks(value1,value2).Result.ToListAsync();

Desta forma, você pode chamar procedimentos SQL brutos.


Os FromSqlparâmetros podem ser simplesmente passados ​​sem criar SqlParameterobjeto: FromSql($"STORED_PROCEDURE {value1}, {value2}")ou FromSql("STORED_PROCEDURE {0}, {1}", value1, value2)(eles serão escapados).
Majid de

7

Você pode usar isso (em https://github.com/aspnet/EntityFrameworkCore/issues/1862#issuecomment-451671168 ):

public static class SqlQueryExtensions
{
    public static IList<T> SqlQuery<T>(this DbContext db, string sql, params object[] parameters) where T : class
    {
        using (var db2 = new ContextForQueryType<T>(db.Database.GetDbConnection()))
        {
            return db2.Query<T>().FromSql(sql, parameters).ToList();
        }
    }

    private class ContextForQueryType<T> : DbContext where T : class
    {
        private readonly DbConnection connection;

        public ContextForQueryType(DbConnection connection)
        {
            this.connection = connection;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            // switch on the connection type name to enable support multiple providers
            // var name = con.GetType().Name;
            optionsBuilder.UseSqlServer(connection, options => options.EnableRetryOnFailure());

            base.OnConfiguring(optionsBuilder);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Query<T>();
            base.OnModelCreating(modelBuilder);
        }
    }
}

E o uso:

    using (var db = new Db())
    {
        var results = db.SqlQuery<ArbitraryType>("select 1 id, 'joe' name");
        //or with an anonymous type like this
        var results2 = db.SqlQuery(() => new { id =1, name=""},"select 1 id, 'joe' name");
    }

6

Adicionar pacote Nuget - Microsoft.EntityFrameworkCore.Relational

using Microsoft.EntityFrameworkCore;
...
await YourContext.Database.ExecuteSqlCommandAsync("... @p0, @p1", param1, param2 ..)

Isso retornará os números da linha como um inteiro

Consulte - https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.relationaldatabasefacadeextensions.executesqlcommand?view=efcore-3.0


3
Observe que isso retornará apenas o número de linhas afetadas pelo comando: stackoverflow.com/a/49861799/299756
kalyfe

Exatamente o que preciso. Estou usando o Microsoft.EntityFrameworkCore 3.1.1 e não há como executar consulta RAW e SP. Muito obrigado por isso!
Jaysonragasa

5

tente isto: (criar método de extensão)

public static List<T> ExecuteQuery<T>(this dbContext db, string query) where T : class, new()
        {
            using (var command = db.Database.GetDbConnection().CreateCommand())
            {
                command.CommandText = query;
                command.CommandType = CommandType.Text;

                db.Database.OpenConnection();

                using (var reader = command.ExecuteReader())
                {
                    var lst = new List<T>();
                    var lstColumns = new T().GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToList();
                    while (reader.Read())
                    {
                        var newObject = new T();
                        for (var i = 0; i < reader.FieldCount; i++)
                        {
                            var name = reader.GetName(i);
                            PropertyInfo prop = lstColumns.FirstOrDefault(a => a.Name.ToLower().Equals(name.ToLower()));
                            if (prop == null)
                            {
                                continue;
                            }
                            var val = reader.IsDBNull(i) ? null : reader[i];
                            prop.SetValue(newObject, val, null);
                        }
                        lst.Add(newObject);
                    }

                    return lst;
                }
            }
        }

Uso:

var db = new dbContext();
string query = @"select ID , Name from People where ... ";
var lst = db.ExecuteQuery<PeopleView>(query);

meu modelo: (não em DbSet):

public class PeopleView
{
    public int ID { get; set; }
    public string Name { get; set; }
}

testado em .netCore 2.2 and 3.0.

Nota: esta solução tem desempenho lento


Tente pesquisar PropertyInfo por nome apenas uma vez para um primeiro registro apenas e construir array de PropertyInfo [] por índices de coluna para usar nos próximos registros.
Petr Voborník

@AminRostami Bom trabalho
sebu

2

Não visando diretamente o cenário do OP, mas como tenho lutado com isso, gostaria de abandonar esses ex. métodos que tornam mais fácil executar SQL bruto com DbContext:

public static class DbContextCommandExtensions
{
  public static async Task<int> ExecuteNonQueryAsync(this DbContext context, string rawSql,
    params object[] parameters)
  {
    var conn = context.Database.GetDbConnection();
    using (var command = conn.CreateCommand())
    {
      command.CommandText = rawSql;
      if (parameters != null)
        foreach (var p in parameters)
          command.Parameters.Add(p);
      await conn.OpenAsync();
      return await command.ExecuteNonQueryAsync();
    }
  }

  public static async Task<T> ExecuteScalarAsync<T>(this DbContext context, string rawSql,
    params object[] parameters)
  {
    var conn = context.Database.GetDbConnection();
    using (var command = conn.CreateCommand())
    {
      command.CommandText = rawSql;
      if (parameters != null)
        foreach (var p in parameters)
          command.Parameters.Add(p);
      await conn.OpenAsync();
      return (T)await command.ExecuteScalarAsync();
    }
  }
}

1

Usei Dapper para contornar essa restrição do Entity Framework Core.

IDbConnection.Query

está trabalhando com consulta sql ou procedimento armazenado com vários parâmetros. A propósito, é um pouco mais rápido (veja os testes de benchmark )

Dapper é fácil de aprender. Demorou 15 minutos para escrever e executar o procedimento armazenado com parâmetros. De qualquer forma, você pode usar EF e Dapper. Abaixo está um exemplo:

 public class PodborsByParametersService
{
    string _connectionString = null;


    public PodborsByParametersService(string connStr)
    {
        this._connectionString = connStr;

    }

    public IList<TyreSearchResult> GetTyres(TyresPodborView pb,bool isPartner,string partnerId ,int pointId)
    {

        string sqltext  "spGetTyresPartnerToClient";

        var p = new DynamicParameters();
        p.Add("@PartnerID", partnerId);
        p.Add("@PartnerPointID", pointId);

        using (IDbConnection db = new SqlConnection(_connectionString))
        {
            return db.Query<TyreSearchResult>(sqltext, p,null,true,null,CommandType.StoredProcedure).ToList();
        }


        }
}

0

Você também pode usar QueryFirst . Como Dapper, isso está totalmente fora da EF. Ao contrário do Dapper (ou EF), você não precisa manter o POCO, você edita o SQL SQL em um ambiente real e ele é continuamente revalidado no banco de dados. Isenção de responsabilidade: sou o autor de QueryFirst.


0

Meu caso usou procedimento armazenado em vez de SQL bruto

Criou uma classe

Public class School
{
    [Key]
    public Guid SchoolId { get; set; }
    public string Name { get; set; }
    public string Branch { get; set; }
    public int NumberOfStudents  { get; set; }
}

Adicionado abaixo na minha DbContextaula

public DbSet<School> SP_Schools { get; set; }

Para executar o procedimento armazenado:

var MySchools = _db.SP_Schools.FromSqlRaw("GetSchools @schoolId, @page, @size ",
              new SqlParameter("schoolId", schoolId),
              new SqlParameter("page", page),
              new SqlParameter("size", size)))
.IgnoreQueryFilters();


0

Esta solução se apóia fortemente na solução de @pius. Eu queria adicionar a opção de suporte a parâmetros de consulta para ajudar a mitigar a injeção de SQL e também queria torná-la uma extensão do DbContext DatabaseFacade para Entity Framework Core para torná-la um pouco mais integrada.

Primeiro crie uma nova classe com a extensão:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;

namespace EF.Extend
{

    public static class ExecuteSqlExt
    {
        /// <summary>
        /// Execute raw SQL query with query parameters
        /// </summary>
        /// <typeparam name="T">the return type</typeparam>
        /// <param name="db">the database context database, usually _context.Database</param>
        /// <param name="query">the query string</param>
        /// <param name="map">the map to map the result to the object of type T</param>
        /// <param name="queryParameters">the collection of query parameters, if any</param>
        /// <returns></returns>
        public static List<T> ExecuteSqlRawExt<T, P>(this DatabaseFacade db, string query, Func<DbDataReader, T> map, IEnumerable<P> queryParameters = null)
        {
            using (var command = db.GetDbConnection().CreateCommand())
            {
                if((queryParameters?.Any() ?? false))
                    command.Parameters.AddRange(queryParameters.ToArray());

                command.CommandText = query;
                command.CommandType = CommandType.Text;

                db.OpenConnection();

                using (var result = command.ExecuteReader())
                {
                    var entities = new List<T>();

                    while (result.Read())
                    {
                        entities.Add(map(result));
                    }

                    return entities;
                }
            }
                
        }
    }

}

Observe acima que "T" é o tipo para o retorno e "P" é o tipo de seus parâmetros de consulta que irão variar dependendo se você está usando MySql, Sql, etc.

A seguir, mostraremos um exemplo. Estou usando o recurso MySql EF Core, então veremos como podemos usar a extensão genérica acima com esta implementação mais específica do MySql:

//add your using statement for the extension at the top of your Controller
//with all your other using statements
using EF.Extend;

//then your your Controller looks something like this
namespace Car.Api.Controllers
{

    //Define a quick Car class for the custom return type
    //you would want to put this in it's own class file probably
    public class Car
    {
        public string Make { get; set; }
        public string Model { get; set; }
        public string DisplayTitle { get; set; }
    }

    [ApiController]
    public class CarController : ControllerBase
    {
        private readonly ILogger<CarController> _logger;
        //this would be your Entity Framework Core context
        private readonly CarContext _context;

        public CarController(ILogger<CarController> logger, CarContext context)
        {
            _logger = logger;
            _context = context;
        }

        //... more stuff here ...

       /// <summary>
       /// Get car example
       /// </summary>
       [HttpGet]
       public IEnumerable<Car> Get()
       {
           //instantiate three query parameters to pass with the query
           //note the MySqlParameter type is because I'm using MySql
           MySqlParameter p1 = new MySqlParameter
           {
               ParameterName = "id1",
               Value = "25"
           };

           MySqlParameter p2 = new MySqlParameter
           {
               ParameterName = "id2",
               Value = "26"
           };

           MySqlParameter p3 = new MySqlParameter
           {
               ParameterName = "id3",
               Value = "27"
           };

           //add the 3 query parameters to an IEnumerable compatible list object
           List<MySqlParameter> queryParameters = new List<MySqlParameter>() { p1, p2, p3 };

           //note the extension is now easily accessed off the _context.Database object
           //also note for ExecuteSqlRawExt<Car, MySqlParameter>
           //Car is my return type "T"
           //MySqlParameter is the specific DbParameter type MySqlParameter type "P"
           List<Car> result = _context.Database.ExecuteSqlRawExt<Car, MySqlParameter>(
        "SELECT Car.Make, Car.Model, CONCAT_WS('', Car.Make, ' ', Car.Model) As DisplayTitle FROM Car WHERE Car.Id IN(@id1, @id2, @id3)",
        x => new Car { Make = (string)x[0], Model = (string)x[1], DisplayTitle = (string)x[2] }, 
        queryParameters);

           return result;
       }
    }
}

A consulta retornaria linhas como:
"Ford", "Explorer", "Ford Explorer"
"Tesla", "Model X", "Tesla Model X"

O título de exibição não é definido como uma coluna do banco de dados, então não faria parte do modelo EF Car por padrão. Gosto dessa abordagem como uma das muitas soluções possíveis. As outras respostas nesta página fazem referência a outras maneiras de resolver esse problema com o decorador [NotMapped], que dependendo do seu caso de uso pode ser a abordagem mais apropriada.

Observe que o código neste exemplo é obviamente mais detalhado do que precisa ser, mas achei que deixou o exemplo mais claro.


-6

Com o Entity Framework 6 você pode executar algo como abaixo

Criar classe modal como

Public class User
{
        public int Id { get; set; }
        public string fname { get; set; }
        public string lname { get; set; }
        public string username { get; set; }
}

Execute o comando Raw DQL SQl conforme abaixo:

var userList = datacontext.Database.SqlQuery<User>(@"SELECT u.Id ,fname , lname ,username FROM dbo.Users").ToList<User>();
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.