DbSetなしの生SQLクエリ-Entity Framework Core


107

Entity Framework Coreを削除すると dbData.Database.SqlQuery<SomeModel>と、全文検索クエリの生のSQLクエリを作成してテーブルデータとランクも返すソリューションを見つけることができません。

Entity Framework Coreで生のSQLクエリを作成するために私が見た唯一の方法はvia dbData.Product.FromSql("SQL SCRIPT");で、クエリで返すランクをマップするDbSetがないため、これは役に立ちません。

何か案は???


15
特定のユースケースで単純なDTOが本当に必要なだけのときは、SqlQuery <T>が大幅に欠落し、カスタムクラスをDbContextにマップする必要はありません。私はこの機能をEF Coreに追加し直すことを要求するユーザーボイスを作成しました。この機能を希望する場合は誰でも投票できます。data.uservoice.com
Matt Sanders

1
github.com/aspnet/EntityFramework/issues/1862によると、これはEFコア1.2または1.1.0-preview1を対象としています
Dan Field

2
@Devonが今言ったことに基づいて、私はあまりに長い時間を費やして、それらがMicrosoft.EntityFrameworkCore.SqlServerの拡張メソッドであることを理解しました。これらの拡張メソッドを取得する前に、それをプロジェクトに追加する必要があります。
Daniel

3
ため息をつく「人々はこれを望んする必要はありません」:これはアーキテクチャ宇宙飛行士の決定のいくつかの種類のように思えます。この場合にのみ、Dapperをインストールする必要があると思います。迷惑です。
Dirk Boer

1
@MattSanders-あなたはuservoiceリンクですが、しばらくの間は死んでいるようです。どこへ行ったのか知っていますか?
Dirk Boer

回答:


125

EF Core 2.1またはEF Core 3以降のバージョンを使用しているかどうかによって異なります

EF Core 2.1を使用している場合

2018年5月7日以降に利用可能なEF Core 2.1リリース候補1を使用している場合は、クエリタイプである提案された新機能を利用できます。

何がクエリの種類は

エンティティタイプに加えて、EF Coreモデルにはクエリタイプを含めることができます。これを使用して、エンティティタイプにマップされていないデータに対してデータベースクエリを実行できます。

クエリタイプを使用する場合

アドホックFromSql()クエリの戻り値の型として機能します。

データベースビューへのマッピング。

主キーが定義されていないテーブルへのマッピング。

モデルで定義されたクエリへのマッピング。

したがって、質問への回答として提案されているすべてのハックや回避策を実行する必要はありません。次の手順に従ってください。

まず、タイプの新しいプロパティ定義されたSQLクエリの列の値を運ぶクラスの型であるが。だからあなたの中にこれがあります:DbQuery<T>TDbContext

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

次に、次のようにFromSqlメソッドを使用しますDbSet<T>

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

また、DdContextsは部分クラスであるため、1つ以上の個別のファイルを作成して、「生のSQL DbQuery」定義を最適に編成することができます。


EF Core 3.0以降のバージョンを使用している場合

クエリタイプは、キーレスエンティティタイプと呼ばれるようになりました。上記のように、クエリの種類はEF Core 2.1で導入されました。EF Core 3.0以降のバージョンを使用している場合は、クエリタイプが廃止されたとマークされているため、キーレスtntityタイプの使用を検討する必要があります。

この機能は、クエリの種類の名前でEF Core 2.1に追加されました。EF Core 3.0では、この概念の名前がキーレスエンティティタイプに変更されました。[Keyless] Data AnnotationはEFCore 5.0で利用可能になりました。

キーレスエンティティタイプをいつ使用するかについては、クエリタイプと同じシナリオがまだあります。

したがって、それを使用するには、最初にクラスSomeModel[Keyless]データアノテーションを付けるか、.HasNoKey()以下のようなメソッド呼び出しで流暢な構成を行う必要があります。

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

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

その構成後、ここで説明する方法の1つを使用してSQLクエリを実行できます。たとえば、これを使用できます。

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

18
この回答は、EF Core 2.1以降を使用する場合に最適なソリューションです。👍
ウィル黄

2
@CodeNotFound結果が必要ない場合、またはプリミティブ型(たとえばbit)の場合はどうなりますか?
Shimmy Weitzhandler 2018

5
CodeFirstを使用すると、これらすべてのプロパティを含むテーブルが自動的に作成さ[NotMapped]れ、SomeModelsクラスに追加しても機能しません。私は何かを逃しましたか?
Jean-Paul

7
EF Core 3.0は、キーレスエンティティタイプでのDbQuery使用DbSetを優先して非推奨になりました。
NetMage

3
参考までに、EF core 3.0のバグのため、コードファーストの移行では、HasNoKey()でマークされたエンティティでもテーブルを作成しようとします。したがって、.ToView(null)も追加する必要があります。例:modelBuilder.Entity<MyData>().HasNoKey().ToView(null);@ Jean-Paulこれで問題が解決すると思います
stann1

36

他の答えに基づいて、私はこのヘルパーを作成し、使用例を含め、タスクを実行します。

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;
                }
            }
        }
    }

使用法:

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}"));

組み込みのサポートが追加されたらすぐに取り除く予定です。EF CoreチームのArthur Vickersの声明によると、それはポスト2.0の優先事項です。問題はここで追跡されています


いい答え、それが好きだった。
セブ

31

EF Coreでは、「フリー」の未加工SQLを実行できなくなりました。POCOクラスとDbSetそのクラスのを定義する必要があります。あなたの場合、ランクを定義する必要があります:

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

確実に読み取り専用になるので、.AsNoTracking()呼び出しを含めると便利です。

編集-EF Core 3.0の重大な変更:

DbQuery()は廃止され、代わりにDbSet()を使用する必要があります(再度)。キーレスエンティティがある場合、つまり主キーを必要としない場合は、HasNoKey()メソッドを使用できます。

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

詳細については、こちらをご覧ください


3
したがってDbContext、新しいプロパティを含めるようにを拡張する必要があると思いますDbSet<Rank> Rank { get; set; }。これは今、linqに関してどのような影響がありますか?DBContext.Rank.Where(i => i.key == 1)つまり、のようなステートメントを使用できるようになったわけではありません。このステートメントはSQLに実装されていないため、失敗しませんか?
David Harlow、

このセットに対して発行されたLinqはメモリで解決する必要があります。別のWHERE sql句を発行する必要がある場合は、それらをパラメータとして含めるか、別のスクリプトを作成する必要があります。
E-Bat

私のDbSetには「FromSql」メソッドがありません。これは私が見逃している拡張機能ですか?
birwin 2017

1
@birwin、名前空間Microsoft.EntityFrameworkCoreをインポートする必要があります
E-Bat

20

EF Coreで生のSQLを実行できます-このクラスをプロジェクトに追加します。これにより、POCOとDBSetを定義しなくても、生のSQLを実行して生の結果を取得できます。元の例については、https://github.com/aspnet/EntityFramework/issues/1862#issuecomment-220787464を参照してください

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);
            }
        }
    }
}

これを使用する方法の例を次に示します。

// 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

今のところ、EFCoreから何か新しいものがあるまで、コマンドを使用して手動でマッピングします

  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
         }
      }
  }

SQLインジェクションを回避するためにSqlParameterを試してください。

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

FromSqlは完全なクエリでは機能しません。たとえば、WHERE句を含めたい場合は無視されます。

いくつかのリンク:

Entity Framework Coreを使用して生のSQLクエリを実行する

生のSQLクエリ


7

Core 2.1では、次のようなことができます。

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

次に、SQLプロシージャを次のように定義します。

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;
}

この方法では、ランクモデルはDBに作成されません。

コントローラ/アクションで次のように呼び出すことができます:

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

このようにして、Raw SQLプロシージャを呼び出すことができます。


FromSqlparamsが単に作成せずに渡すことができますSqlParameter:オブジェクトをFromSql($"STORED_PROCEDURE {value1}, {value2}")FromSql("STORED_PROCEDURE {0}, {1}", value1, value2)(彼らはエスケープされます)。
マジッド

7

これを使用できます(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);
        }
    }
}

そして使用法:

    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

Nugetパッケージを追加する-Microsoft.EntityFrameworkCore.Relational

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

これは、整数として行番号を返します

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


3
これはコマンドの影響を受ける行数のみを返すことに注意してください:stackoverflow.com/a/49861799/299756
kalyfe

まさに私が必要とするもの。Microsoft.EntityFrameworkCore 3.1.1を使用していますが、RAWクエリとSPを実行する方法がありません。どうもありがとうございました!
ジェイソンラガサ

5

これを試してください:(拡張メソッドを作成します)

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;
                }
            }
        }

使用法:

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

私のモデル:(ではないDbSet):

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

でテスト.netCore 2.2 and 3.0

注:このソリューションはパフォーマンスが遅い


最初のレコードに対してのみ名前でPropertyInfoを検索し、次のレコードで使用するために列インデックスでPropertyInfo []の配列を作成してください。
PetrVoborník

@AminRostamiナイスワーク
セブ

2

OPのシナリオを直接対象とするのではなく、私はこれに苦労してきたので、これらのexをドロップしたいと思います。で生のSQLを簡単に実行できるようにするメソッド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

Dapperを使用して、エンティティフレームワークコアのこの制約をバイパスしました。

IDbConnection.Query

は、SQLクエリまたは複数のパラメータを持つストアドプロシージャを使用しています。ちなみに少し高速です(ベンチマークテストを参照)

Dapperは簡単に習得できます。パラメータ付きのストアドプロシージャを記述して実行するのに15分かかりました。とにかく、EFとDapperの両方を使用できます。以下に例を示します。

 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

QueryFirstを使用することもできます。Dapperのように、これは完全にEFの外にあります。Dapper(またはEF)とは異なり、POCOを維持する必要はなく、SQL SQLを実際の環境で編集すると、DBに対して継続的に再検証されます。免責事項:私はQueryFirstの作成者です。


0

私のケースは生のSQLではなくストアドプロシージャを使用しました

クラスを作成しました

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

DbContextクラスに以下を追加しました

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

ストアドプロシージャを実行するには:

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


0

このソリューションは、@ piusのソリューションに大きく依存しています。SQLインジェクションを軽減するためにクエリパラメーターをサポートするオプションを追加したいと思いました。また、それをDbContext DatabaseFacade for Entity Framework Coreから拡張してもう少し統合したいと考えていました。

まず、拡張子を持つ新しいクラスを作成します。

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;
                }
            }
                
        }
    }

}

上記の「T」は戻り値のタイプであり、「P」はMySql、Sqlなどを使用しているかどうかによって異なるクエリパラメータのタイプであることに注意してください。

次に例を示します。私はMySql EF Core機能を使用しているので、このより具体的な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;
       }
    }
}

クエリは
、「Ford」、「Explorer」、「Ford Explorer」のような行を返します。
「Tesla」、「Model X」、「Tesla Model X」の。

表示タイトルはデータベース列として定義されていないため、デフォルトではEF Carモデルの一部にはなりません。このアプローチは、多くの可能なソリューションの1つとして気に入っています。このページの他の回答は、[NotMapped]デコレーターを使用してこの問題に対処する他の方法を参照しています。これは、ユースケースによっては、より適切なアプローチになる場合があります。

この例のコードは必要以上に冗長であることは明らかですが、例を明確にすることで考えました。


-6

Entity Framework 6では、以下のようなものを実行できます

モーダルクラスを作成

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

以下のようにRaw DQL SQlコマンドを実行します。

var userList = datacontext.Database.SqlQuery<User>(@"SELECT u.Id ,fname , lname ,username FROM dbo.Users").ToList<User>();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.