সত্তা ফ্রেমওয়ার্ক দ্বারা উত্পন্ন এসকিউএলকে আমি কীভাবে দেখতে পারি?


624

সত্তা কাঠামোর দ্বারা উত্পন্ন এসকিউএলকে আমি কীভাবে দেখতে পারি?

(আমার বিশেষ ক্ষেত্রে আমি মাইএসকিএল সরবরাহকারী ব্যবহার করছি - যদি তা গুরুত্বপূর্ণ হয়)


1
এই দুটিই MSDN পত্রিকা থেকে artice সত্তা ফ্রেমওয়ার্ক জন্য কিছু প্রোফাইলিং অপশন বর্ণনা 4
Arve

2
লিঙ্কযুক্ত "সদৃশ" প্রশ্নটি লিনকিউ থেকে এসকিউএল এর জন্য, সুতরাং এটি আসলে কোনও সদৃশ নয়।
জুরমেল

2
ডিবাগারের অধীনে চলাকালীন, ইন্টেলিট্রেস এসকিউএল অনুসন্ধানগুলি দেখায়, যদিও তাদের ফলাফল ছাড়াই।
ivan_pozdeev

আপনি যদি বিকাশের সময় এসকিউএলটি দেখতে আগ্রহী হন তবে আপনি লিনিকপ্যাড ব্যবহার করতে পারেন । আপনি যখন ফলাফলগুলিতে একটি লিনকিউ ক্যোয়ারি চালাবেন তখন একটি এসকিউএল ট্যাব উপস্থিত থাকবে যা সম্পাদিত এসকিউএল বিবৃতি প্রদর্শন করে। মাইএসকিউএলের জন্য আপনাকে ড্রাইভার ইনস্টল করতে হবে। আমার কাছে একটি মাইএসকিউএল ডাটাবেস উপলব্ধ নেই, তবে এটি কাজ করা উচিত।
gligoran

উত্তর:


472

আপনি নিম্নলিখিতটি করতে পারেন:

IQueryable query = from x in appEntities
             where x.id == 32
             select x;

var sql = ((System.Data.Objects.ObjectQuery)query).ToTraceString();

বা EF6 এ:

var sql = ((System.Data.Entity.Core.Objects.ObjectQuery)query)
            .ToTraceString();

এটি আপনাকে যে এসকিউএল উত্পন্ন হয়েছিল তা দেবে।


20
আপনি .Single (),। অ্যাকাউন্ট (), .এই () ইত্যাদি দিয়ে শেষ হওয়া প্রশ্নের জন্য এসকিউএল পাবেন না।
বসন্তের 76

24
এটি কারণ .Single()আপনার অবজেক্টটি চালানোর পরে IQueryableআর অনুমান করি না।
সুহাস

11
EF6 এর সাথে, আমি এটি কেবল প্রতিচ্ছবি দিয়েই পেতে পারি। তবে প্রথমে, আমাকে রূপান্তর resultকরতে হয়েছিল System.Data.Entity.Infrastructure.DbQuery<T>, তারপরে অভ্যন্তরীণ সম্পত্তি InternalQueryহিসাবে (System.Data.Entity.Internal.Linq.InternalQuery<T>)ToTraceString()
পেয়েছিল

9
System.Data.Entity, System.Data.Objects.ObjectQuery এর রেফারেন্স উপরের dll তে বিদ্যমান
মহেশ

54
EF6 এ আপনি ঠিক করতে পারেনresult.ToString()
স্কট চেম্বারলাইন

955

অ্যান্টিটি ফ্রেমওয়ার্ক 6 এবং তার বেশি বয়সীদের জন্য, আপনি যদি ভিজ্যুয়াল স্টুডিওতে এসকিউএল আউটপুট দেখতে চান (যেমন আমি করেছি) আপনাকে নতুন লগিং / ইন্টারসেপশন কার্যকারিতা ব্যবহার করতে হবে।

নিম্নলিখিত লাইনটি যুক্ত করা ভিজ্যুয়াল স্টুডিও আউটপুট প্যানেলে উত্পন্ন এসকিউএল (অতিরিক্ত কার্যকর-সম্পর্কিত বিবরণ সহ) কেটে ফেলবে:

using (MyDatabaseEntities context = new MyDatabaseEntities())
{
    context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
    // query the database using EF here.
}

এই নিফটি ব্লগ সিরিজে EF6 এ লগ ইন সম্পর্কে আরও তথ্য: http://blog.oneunicorn.com/2013/05/08/ef6-sql-logging-part-1-simple-logging/

দ্রষ্টব্য: আপনি নিজের প্রকল্পটি DEBUG মোডে চালাচ্ছেন তা নিশ্চিত করুন।


107
এই উত্তরটি আরও বেশি ভালবাসার দাবিদার হয়েছে (যদি আপনি EF6 + ব্যবহার করেন) - দুর্দান্ত ডিবাগ সংযোজন, কেবল এটি ডিবিসিন্টেক্সট কনস্ট্রাক্টারে যুক্ত করুন (এটি.ডাটাবেস.লগ = ...)
কীথল 8041

21
আপনি নিজের প্রকল্পটি ডেবগ মোডে চালাচ্ছেন কিনা তা নিশ্চিত করুন, "ডিবাগ" আইটেমটি আউটপুট ফলকের কম্বোবক্সে নির্বাচন করেছে কিনা তাও পরীক্ষা করে দেখুন এবং আপনার ডিবাগটি তাত্ক্ষণিক (সরঞ্জামসমূহ> বিকল্পগুলি> ডিবাগিং> সমস্ত আউটপুট উইন্ডো পাঠ্যকে পুনঃনির্দেশিত করছে না) তা পরীক্ষা করে দেখুন উইন্ডো)
rkawano

5
ভ্যারিয়েবলের মানগুলি সরাসরি উত্পন্ন স্কয়ারের মধ্যে অন্তর্ভুক্ত করার জন্য কি এটি পাওয়ার উপায় আছে? বড়দের সাথে একটি ব্যথা বিট।
ক্রিস

22
@ ম্যাট নিবেকার এটি ইএফ কোরটিতে কাজ করে না। EF কোর এর বিকল্প কি?
নাম

9
সতর্কতা: আমি এটি কেবলমাত্র বিকাশে চালানোর অভিপ্রায় নিয়ে এটি প্রয়োগ করেছি। যখন আমরা আমাদের পরীক্ষার পরিবেশে নিযুক্ত হয়ে যাই, আমরা হঠাৎ করে আইআইএস কর্মী প্রক্রিয়াতে মেমরি ফাঁস দেখতে শুরু করি। মেমোরি প্রোফাইলিংয়ের পরে, আমরা বুঝতে পেরেছিলাম এমনকি সুস্পষ্ট জিসি সত্তা প্রসঙ্গের অবজেক্টগুলি আর সংগ্রহ করছে না (হ্যাঁ, তারা বিবৃতিগুলি ব্যবহার করছে)। এই লাইনটি সরিয়ে সমস্ত স্বাভাবিক অবস্থায় ফিরে আসে। সুতরাং, যদিও এটি দুর্দান্ত সরঞ্জাম, আপনি এটি কেবল বিকাশের জন্য আপনার অ্যাপ্লিকেশনটিতে তৈরি করেছেন তা নিশ্চিত করুন।
ব্র্যান্ডন বার্কলে

82

EF6.1 দিয়ে শুরু করে আপনি একটি ডাটাবেস লগার নিবন্ধনের জন্য ইন্টারসেপ্টর ব্যবহার করতে পারেন। একটি ফাইলে অধ্যায়গুলির "interceptors" এবং "লগিং ডাটাবেস অপারেশনস" দেখ এখানে

<interceptors> 
  <interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework"> 
    <parameters> 
      <parameter value="C:\Temp\LogOutput.txt"/> 
      <parameter value="true" type="System.Boolean"/> 
    </parameters> 
  </interceptor> 
</interceptors>


12
যথার্থতা, এটি এর অধীনে রয়েছে: <কনফিগারেশন> <entityFramework> <অন্তর্নিবেশকারীদের ... ... << অন্তঃসত্ত্বাবন্ধি> </ i> <ফ্রেমওয়ার্ক> << কনফিগারেশন>
ক্রিস্টোফ পি

80

আপনি যদি ডিবি কনটেক্সট ব্যবহার করেন তবে এসকিউএল পাওয়ার জন্য আপনি নিম্নলিখিতটি করতে পারেন:

var result = from i in myContext.appEntities
             select new Model
             {
                 field = i.stuff,
             };
var sql = result.ToString();

12
ToString()p__linq__0চূড়ান্ত মানগুলির পরিবর্তে (যেমন: 34563 এর পরিবর্তে p__linq__0)
স্পোর্টস

24

EF 6.0 এবং ততোধিকের জন্য প্রযোজ্য: আপনারা যারা লগিং কার্যকারিতা সম্পর্কে আরও জানতে চান এবং ইতিমধ্যে প্রদত্ত কিছু উত্তর যুক্ত করেছেন।

EF থেকে ডাটাবেসে প্রেরিত যে কোনও কমান্ড এখন লগইন করা যেতে পারে। EF 6.x থেকে উত্পন্ন উত্সগুলি দেখতে, ব্যবহার করুনDBContext.Database.Log property

কি লগড হয়

 - SQL for all different kinds of commands. For example:
    - Queries, including normal LINQ queries, eSQL queries, and raw queries from methods such as SqlQuery.
    - Inserts, updates, and deletes generated as part of SaveChanges
    - Relationship loading queries such as those generated by lazy loading
 - Parameters
 - Whether or not the command is being executed asynchronously
 - A timestamp indicating when the command started executing
 - Whether or not the command completed successfully, failed by throwing an exception, or, for async, was canceled
 - Some indication of the result value
 - The approximate amount of time it took to execute the command. Note that this is the time from sending the command to getting the result object back. It does not include time to read the results.

উদাহরণ:

using (var context = new BlogContext()) 
{ 
    context.Database.Log = Console.Write; 

    var blog = context.Blogs.First(b => b.Title == "One Unicorn"); 

    blog.Posts.First().Title = "Green Eggs and Ham"; 

    blog.Posts.Add(new Post { Title = "I do not like them!" }); 

    context.SaveChangesAsync().Wait(); 
}

আউটপুট:

SELECT TOP (1)
    [Extent1].[Id] AS [Id],
    [Extent1].[Title] AS [Title]
    FROM [dbo].[Blogs] AS [Extent1]
    WHERE (N'One Unicorn' = [Extent1].[Title]) AND ([Extent1].[Title] IS NOT NULL)
-- Executing at 10/8/2013 10:55:41 AM -07:00
-- Completed in 4 ms with result: SqlDataReader

SELECT
    [Extent1].[Id] AS [Id],
    [Extent1].[Title] AS [Title],
    [Extent1].[BlogId] AS [BlogId]
    FROM [dbo].[Posts] AS [Extent1]
    WHERE [Extent1].[BlogId] = @EntityKeyValue1
-- EntityKeyValue1: '1' (Type = Int32)
-- Executing at 10/8/2013 10:55:41 AM -07:00
-- Completed in 2 ms with result: SqlDataReader

UPDATE [dbo].[Posts]
SET [Title] = @0
WHERE ([Id] = @1)
-- @0: 'Green Eggs and Ham' (Type = String, Size = -1)
-- @1: '1' (Type = Int32)
-- Executing asynchronously at 10/8/2013 10:55:41 AM -07:00
-- Completed in 12 ms with result: 1

INSERT [dbo].[Posts]([Title], [BlogId])
VALUES (@0, @1)
SELECT [Id]
FROM [dbo].[Posts]
WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()
-- @0: 'I do not like them!' (Type = String, Size = -1)
-- @1: '1' (Type = Int32)
-- Executing asynchronously at 10/8/2013 10:55:41 AM -07:00
-- Completed in 2 ms with result: SqlDataReader

একটি বাহ্যিক ফাইল লগ করতে:

using (var context = new BlogContext()) 
{  
    using (var sqlLogFile = new StreamWriter("C:\\temp\\LogFile.txt"))
    {          
         context.Database.Log = sqlLogFile.Write;     
         var blog = context.Blogs.First(b => b.Title == "One Unicorn"); 
         blog.Posts.First().Title = "Green Eggs and Ham"; 
         context.SaveChanges();
   }
}

এখানে আরও তথ্য: লগিং এবং অবিচ্ছিন্ন ডাটাবেস অপারেশনস


21

আপনি EF 4.1 এ নিম্নলিখিতটি করতে পারেন:

var result = from x in appEntities
             where x.id = 32
             select x;

System.Diagnostics.Trace.WriteLine(result .ToString());

এটি আপনাকে যে এসকিউএল উত্পন্ন হয়েছিল তা দেবে।


1
সত্যিকার অর্থে, আমি বিশ্বাস করি এটি কেবল তখনই কাজ করে যখন ক্যোয়ারী কোনও বেনামি প্রকারটি দেয়। যদি এটি কোনও কাস্টম প্রকারটি ফেরত দেয় তবে ToString()আউটপুটটি সেই কাস্টম প্রকারের নাম স্থান sp উদাহরণস্বরূপ, উপরের কোডটি যদি ছিল select new CustomType { x = x.Name }তবে প্রত্যাশিত মানটি Company.Models.CustomTypeউত্পন্ন এসকিউএল এর পরিবর্তে কিছু হবে ।
চাদ লেভি

8
এই কৌশলটি System.Data.Objects.ObjectQuery``1[MyProject.Models.Product]আমার জন্য উত্পাদন করে ।
কার্ল জি

1
@ কার্লজি সিস্টেম.ডাটা.অবজেক্টস.অবজেক্টকিউরি EF 4.1 (DbContext) নয়। ডিবি কনটেক্সট ব্যবহার করে এটি হবে সিস্টেম.ডাটা.এন্টিটি.ইনফ্রাস্ট্রাক্ট.ডিবিকিউয়ারি `১ [মাইপ্রজেক্ট.মোডেলস.প্রডাক্ট] যা সত্যই এটি "টুস্ট্রিং ()"
স্প্রিংয়ে 76

এটি আপনাকে যে এসকিউএল উত্পন্ন হয়েছিল তা দেবে, আউটপুট উইন্ডোতে কোথায়? ড্রপডাউন থেকে কোন বিকল্প?
জেসন স্ট্যাথাম

17

আমার উত্তর EF কোর ঠিকানা । আমি এই গিথুব ইস্যু এবং কনফিগার করার ক্ষেত্রে ডকগুলি উল্লেখ করিDbContext :

সহজ

ওভাররাইড OnConfiguringআপনার পদ্ধতি DbContextশ্রেণী ( YourCustomDbContext) যেমন এখানে দেখানো একটি ConsoleLoggerProvider ব্যবহার করতে; আপনার প্রশ্নের কনসোলে লগ করা উচিত:

public class YourCustomDbContext : DbContext
{
    #region DefineLoggerFactory
    public static readonly LoggerFactory MyLoggerFactory
        = new LoggerFactory(new[] {new ConsoleLoggerProvider((_, __) => true, true)});
    #endregion


    #region RegisterLoggerFactory
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseLoggerFactory(MyLoggerFactory); // Warning: Do not create a new ILoggerFactory instance each time                
    #endregion
}

জটিল

এই জটিল কেস অগ্রাহ্য এড়াতে পদ্ধতি। , যা ডক্সে নিরুৎসাহিত করা হয়েছে: "পরীক্ষাগুলি সম্পূর্ণ ডাটাবেসটিকে লক্ষ্য না করা পর্যন্ত" এই পদ্ধতির নিজেকে পরীক্ষার জন্য ধার দেওয়া হয় না। "DbContext OnConfiguring

এই কমপ্লেক্স কেসটি ব্যবহার করে:

  • IServiceCollectionমধ্যে Startupবর্গ ConfigureServicesপদ্ধতি (অগ্রাহ্য পরিবর্তে OnConfiguringপদ্ধতি; সুবিধা মধ্যে একটি ঢিলেঢালা কাপলিং DbContextএবং ILoggerProviderআপনি ব্যবহার করতে চান)
  • একটি বাস্তবায়ন ILoggerProvider( ConsoleLoggerProviderউপরের চিত্রটি প্রয়োগের পরিবর্তে ব্যবহারের পরিবর্তে ; আমাদের বাস্তবায়নটি হ'ল আমরা কীভাবে ফাইলটিতে লগইন করব তা দেখায় (আমি কোনও ফাইল লগিং সরবরাহকারীকে ইএফ কোর দিয়ে পাঠানো দেখতে পাই না ))

এটার মত:

public class Startup

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        var lf = new LoggerFactory();
        lf.AddProvider(new MyLoggerProvider());

        services.AddDbContext<YOUR_DB_CONTEXT>(optionsBuilder => optionsBuilder
                .UseSqlServer(connection_string)
                //Using the LoggerFactory 
                .UseLoggerFactory(lf));
        ...
    }
}

এখানে একটি MyLoggerProvider(এবং এটি MyLoggerযা আপনার কনফিগার করতে পারে এমন একটি ফাইলের সাথে এর লগগুলি সংযোজন করে এটি প্রয়োগ করে ; আপনার EF কোর অনুসন্ধানগুলি ফাইলটিতে উপস্থিত হবে))

public class MyLoggerProvider : ILoggerProvider
{
    public ILogger CreateLogger(string categoryName)
    {
        return new MyLogger();
    }

    public void Dispose()
    { }

    private class MyLogger : ILogger
    {
        public bool IsEnabled(LogLevel logLevel)
        {
            return true;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            File.AppendAllText(@"C:\temp\log.txt", formatter(state, exception));
            Console.WriteLine(formatter(state, exception));
        }

        public IDisposable BeginScope<TState>(TState state)
        {
            return null;
        }
    } 
}

সুতরাং ... কোন ভিক্ষুক এটি করার উপায় আছে?
জুয়ান দে লা ক্রুজ

1
@ জুয়ানডেলা ক্রুজ আমি আমার উত্তরটি সহজীকরণ করেছি; সহজ বিকল্পটি ব্যবহার করে দেখুন
দ্য রেড মটর

16

দুটি উপায় আছে:

  1. উত্পন্ন হবে যে এসকিউএল দেখতে, কল করুন ToTraceString()। আপনি এটি আপনার ওয়াচ উইন্ডোতে যুক্ত করতে পারেন এবং কোনও লিনকিউ কোয়েরির জন্য প্রদত্ত বিন্দুতে কোয়েরিটি কী হবে তা দেখার জন্য একটি ব্রেকপয়েন্ট সেট করতে পারেন।
  2. আপনি আপনার পছন্দের এসকিউএল সার্ভারের সাথে একটি ট্রেসার সংযুক্ত করতে পারেন, যা আপনাকে এর সমস্ত বিষাদ বিবরণে চূড়ান্ত কোয়েরি দেখায়। মাইএসকিউএলের ক্ষেত্রে, অনুসন্ধানগুলি সন্ধান করার সহজতম উপায়টি হল কোয়েরি লগের সাহায্যে লেজ রাখা tail -fঅফিসিয়াল ডকুমেন্টেশনে আপনি মাইএসকিউএল এর লগিং সুবিধাগুলি সম্পর্কে আরও শিখতে পারেন । এসকিউএল সার্ভারের জন্য অন্তর্ভুক্ত এসকিউএল সার্ভার প্রোফাইলার ব্যবহার করা সবচেয়ে সহজ উপায়।

27
টুট্রেসস্ট্রিং কি?
সংখ্যা

আমার প্রতিক্রিয়া পোস্ট করার পরে নিক ঠিক যেমন উল্লেখ করেছেন তেমন অবজেক্টকোয়ারি।
বেনিয়ামিন পোল্যাক

2
এসকিউএল সার্ভার প্রোফাইলার প্রথম 4000 টি অক্ষর ক্যাপচার করে, তবে ইএফ কোয়েরিগুলি এর চেয়ে দীর্ঘ হতে পারে।

7

কোডটি পরিবর্তন না করেই কোয়েরিটি সর্বদা কার্যকর রাখার জন্য এটি আপনার ডিবিকন্টেক্সটে যুক্ত করুন এবং ভিজ্যুয়াল স্টুডিওতে আউটপুট উইন্ডোতে এটি পরীক্ষা করুন।

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.Log = (query)=> Debug.Write(query);
    }

@ ম্যাট নিবেক্কার উত্তরের মতো, তবে এটির সাথে আপনাকে এটিকে আপনার বর্তমান কোডে যুক্ত করতে হবে না, যতবার আপনার প্রশ্নের প্রয়োজন হবে।


সেরা উত্তর!
অ্যালেক্সএসসি

7

এসকিউএল পরিচালনার স্টুডিও => সরঞ্জামগুলি => এসকিউএল সার্ভার প্রোফাইলার

ফাইল => নতুন ট্রেস ...

টেমপ্লেট => ফাঁকা ব্যবহার করুন

ইভেন্ট নির্বাচন => টি এসকিউএল

বাম পাশের জন্য চেক করুন: SP.StmtComplete

একটি নির্দিষ্ট অ্যাপ্লিকেশন নাম বা ডাটাবেসনাম নির্বাচন করতে কলাম ফিল্টার ব্যবহার করা যেতে পারে

সেই প্রোফাইলটি চলমান শুরু করুন তারপরে ক্যোয়ারিকে ট্রিগার করুন।

উত্স তথ্যের জন্য এখানে ক্লিক করুন


1
দুঃখিত, কেবল এসকিউএল সার্ভারের জন্য, মাইএসকিউএল নয়
এন্ড্রু পেটে

5

ঠিক আছে, আমি এই মুহুর্তে এই উদ্দেশ্যে এক্সপ্রেস প্রোফাইলার ব্যবহার করছি, অপূর্ণতাটি এটি কেবল এমএস এসকিউএল সার্ভারের জন্য কাজ করে। আপনি এই সরঞ্জামটি এখানে পেতে পারেন: https://expressprofiler.codeplex.com/


5
IQueryable query = from x in appEntities
                   where x.id = 32
                   select x;
var queryString = query.ToString();

বর্গ কোয়েরি ফিরে আসবে। সত্ত্বা ফ্রেমওয়ার্ক 6 এর ডেটাঅন্টেক্সট ব্যবহার করে কাজ করা


4
আমি কেবল এটি চেষ্টা করেছি এবং এটি অবজেক্টটি সন্ধান করে: Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1 [সিস্টেম.লিনক.আইগ্রোপিং 2[System.Int32,String]]আসল কোয়েরির পরিবর্তে। আমি কি কিছু মিস করছি বা আপনি কিছু উল্লেখ করতে ভুলে গেছেন?
লোগঞ্জোন 16

5

আমি ইন্টিগ্রেশন টেস্ট করছি, এবং সত্তা ফ্রেমওয়ার্ক কোর 2.1 এ উত্পন্ন এসকিউএল স্টেটমেন্টটি ডিবাগ করার জন্য এটি প্রয়োজন, তাই আমি এটি ব্যবহার করি DebugLoggerProviderবা ConsoleLoggerProviderপছন্দ করি :

[Fact]
public async Task MyAwesomeTest
    {
        //setup log to debug sql queries
        var loggerFactory = new LoggerFactory();
        loggerFactory.AddProvider(new DebugLoggerProvider());
        loggerFactory.AddProvider(new ConsoleLoggerProvider(new ConsoleLoggerSettings()));

        var builder = new DbContextOptionsBuilder<DbContext>();
        builder
            .UseSqlServer("my connection string") //"Server=.;Initial Catalog=TestDb;Integrated Security=True"
            .UseLoggerFactory(loggerFactory);

        var dbContext = new DbContext(builder.Options);

        ........

এখানে ভিজ্যুয়াল স্টুডিও কনসোল থেকে একটি নমুনা আউটপুট দেওয়া হয়েছে:

নমুনা এসকিউএল স্টেটমেন্ট আউটপুট


1
ডিবাগলগারপ্রাইভাইডার এবং কনসোললগারপ্রাইডারটি কেবলমাত্র নেট নেটওয়ার্কে উপস্থিত রয়েছে বলে মনে হচ্ছে: ডকস.মাইক্রোসফট.কম- ডসনেট
গ্যাব্রিয়েল

4

Necromancing।
এই পৃষ্ঠাটি প্রথম সার্চ ফলাফলের যখন একটি পাবলিক সার্ভিস, কিভাবে এটা EntityFramework মধ্যে সম্পন্ন যে কোন .NET ফ্রেমওয়ার্ক জন্য একটি সমাধান অনুসন্ধানের জন্য, তাই এখানে কোর (.NET জন্য কোর 1 & 2):

var someQuery = (
    from projects in _context.projects
    join issues in _context.issues on projects.Id equals issues.ProjectId into tmpMapp
    from issues in tmpMapp.DefaultIfEmpty()
    select issues
) //.ToList()
;

// string sql = someQuery.ToString();
// string sql = Microsoft.EntityFrameworkCore.IQueryableExtensions.ToSql(someQuery);
// string sql = Microsoft.EntityFrameworkCore.IQueryableExtensions1.ToSql(someQuery);
// using Microsoft.EntityFrameworkCore;
string sql = someQuery.ToSql();
System.Console.WriteLine(sql);

এবং তারপরে এই এক্সটেনশন পদ্ধতিগুলি (। নেট কোর ১.০ এর জন্য আইকিউয়েরেবল এক্সটেনশন 1,। নেট কোর ২.০ এর জন্য আইকিউয়েরেবল এক্সটেনশনগুলি):

using System;
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using Remotion.Linq.Parsing.Structure;


namespace Microsoft.EntityFrameworkCore
{

    // /programming/1412863/how-do-i-view-the-sql-generated-by-the-entity-framework
    // http://rion.io/2016/10/19/accessing-entity-framework-core-queries-behind-the-scenes-in-asp-net-core/

    public static class IQueryableExtensions
    {
        private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo();

        private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo().DeclaredFields
            .First(x => x.Name == "_queryCompiler");

        private static readonly PropertyInfo NodeTypeProviderField =
            QueryCompilerTypeInfo.DeclaredProperties.Single(x => x.Name == "NodeTypeProvider");

        private static readonly MethodInfo CreateQueryParserMethod =
            QueryCompilerTypeInfo.DeclaredMethods.First(x => x.Name == "CreateQueryParser");

        private static readonly FieldInfo DataBaseField =
            QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database");

        private static readonly PropertyInfo DatabaseDependenciesField =
            typeof(Database).GetTypeInfo().DeclaredProperties.Single(x => x.Name == "Dependencies");

        public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class
        {
            if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>))
            {
                throw new ArgumentException("Invalid query");
            }

            var queryCompiler = (QueryCompiler) QueryCompilerField.GetValue(query.Provider);
            var nodeTypeProvider = (INodeTypeProvider) NodeTypeProviderField.GetValue(queryCompiler);
            var parser = (IQueryParser) CreateQueryParserMethod.Invoke(queryCompiler, new object[] {nodeTypeProvider});
            var queryModel = parser.GetParsedQuery(query.Expression);
            var database = DataBaseField.GetValue(queryCompiler);
            var databaseDependencies = (DatabaseDependencies) DatabaseDependenciesField.GetValue(database);
            var queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false);
            var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor();
            modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
            var sql = modelVisitor.Queries.First().ToString();

            return sql;
        }
    }



    public class IQueryableExtensions1
    {
        private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo();

        private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo()
            .DeclaredFields
            .First(x => x.Name == "_queryCompiler");

        private static readonly PropertyInfo NodeTypeProviderField =
            QueryCompilerTypeInfo.DeclaredProperties.Single(x => x.Name == "NodeTypeProvider");

        private static readonly MethodInfo CreateQueryParserMethod =
            QueryCompilerTypeInfo.DeclaredMethods.First(x => x.Name == "CreateQueryParser");

        private static readonly FieldInfo DataBaseField =
            QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database");

        private static readonly FieldInfo QueryCompilationContextFactoryField = typeof(Database).GetTypeInfo()
            .DeclaredFields.Single(x => x.Name == "_queryCompilationContextFactory");


        public static string ToSql<TEntity>(IQueryable<TEntity> query) where TEntity : class
        {
            if (!(query is EntityQueryable<TEntity>) && !(query is InternalDbSet<TEntity>))
            {
                throw new ArgumentException("Invalid query");
            }

            var queryCompiler = (IQueryCompiler) QueryCompilerField.GetValue(query.Provider);

            var nodeTypeProvider = (INodeTypeProvider) NodeTypeProviderField.GetValue(queryCompiler);
            var parser =
                (IQueryParser) CreateQueryParserMethod.Invoke(queryCompiler, new object[] {nodeTypeProvider});
            var queryModel = parser.GetParsedQuery(query.Expression);
            var database = DataBaseField.GetValue(queryCompiler);
            var queryCompilationContextFactory =
                (IQueryCompilationContextFactory) QueryCompilationContextFactoryField.GetValue(database);
            var queryCompilationContext = queryCompilationContextFactory.Create(false);
            var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor();
            modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
            var sql = modelVisitor.Queries.First().ToString();

            return sql;
        }


    }


}

আমি EF কোর 2.0.1 এবং উপরের পরামর্শগুলির ফলাফলগুলি ব্যবহার করছি: System.InuthorCastException: 'Microsoft.EntityFrameworkCore.Query.Intern.InMemoryQueryModelVisitor' '' টাইপ করতে '' Microsoft.EntityFrameworkCore.Query.RerationalisisCelCoderododerCoderCoderCoderCoderCoder 'জন্য টাইপ করুন লাইন: var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor();
ক্রিস ওল্ফ

2
@ ক্রিস ওল্ফ যদি আপনি মূল লেখকের সংক্ষেপ অনুসরণ করেন তবে আপনি এমন কাউকে খুঁজে পেতে পারেন যিনি সেই এক্সটেনশন পদ্ধতির আপডেট সংস্করণ সরবরাহ করেছিলেন । আমার জন্য কাজ করেছেন।
বি

2

আমার ক্ষেত্রে EF 6+ এর জন্য, ক্যোরি স্ট্রিংটি সন্ধানের জন্য তাত্ক্ষণিক উইন্ডোতে এটি ব্যবহার না করে:

var sql = ((System.Data.Entity.Core.Objects.ObjectQuery)query).ToTraceString();

উত্পন্ন এসকিউএল কমান্ডটি পেতে আমি এটি ব্যবহার করে শেষ করেছি:

var sql = ((System.Data.Entity.Infrastructure.DbQuery<<>f__AnonymousType3<string,string,string,short,string>>)query).ToString();

অবশ্যই আপনার বেনামি ধরণের স্বাক্ষর আলাদা হতে পারে।

আছে HTH।


2

আমি সবেমাত্র এটি করেছি:

IQueryable<Product> query = EntitySet.Where(p => p.Id == id);
Debug.WriteLine(query);

এবং ফলাফল আউটপুট প্রদর্শিত :

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Code] AS [Code], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Id] AS [Id1], 
    [Extent2].[FileName] AS [FileName], 
    FROM  [dbo].[Products] AS [Extent1]
    INNER JOIN [dbo].[PersistedFiles] AS [Extent2] ON [Extent1].[PersistedFileId] = [Extent2].[Id]
    WHERE [Extent1].[Id] = @p__linq__0

হ্যাঁ, তবে আমি বিশ্বাস করি যে কেউ p__linq__i দেখতে চায় না, তবে আসল মূল্যবোধগুলি
টম স্টিকেল

এই উপায়ে এখনও EF 6 এ কাজ করে এবং আপনি যদি ক্যোয়ারী কাঠামোর চেহারাটি কেবলমাত্র মনোযোগ দিয়ে থাকেন তবে এটি সহায়ক হবে। আমার ক্ষেত্রে যে প্রকল্পটি আমি আইকিউয়েরেবল তৈরি করব তার <টি> অবজেক্টটিতে সিস্টেম.ডাটা.এন্টিটির কোনও উল্লেখ নেই এবং আমি এটি কেবল ডিবাগিংয়ের উদ্দেশ্যে যুক্ত করতে চাই না। সুতরাং এই পদ্ধতিটি ঠিক কাজ করেছে।
wctiger

2

আমার জন্য, EF6 এবং ভিজ্যুয়াল স্টুডিও 2015 ব্যবহার করে আমি queryতাত্ক্ষণিক উইন্ডোতে প্রবেশ করেছি এবং এটি আমাকে উত্পন্ন এসকিউএল বিবৃতি দিয়েছে


1

আপনি যদি প্যারামিটার মানগুলি (শুধুমাত্র @p_linq_0তাদের মানগুলি নাও ) রাখতে চান IDbCommandInterceptorতবে আপনি ReaderExecutedপদ্ধতিতে কিছু লগিং ব্যবহার করতে এবং যোগ করতে পারেন ।


1

এখানে ভাল উত্তর থাকলেও, কেউই আমার সমস্যাটিকে পুরোপুরি সমাধান করেনি (আমি কোনও আইকিউয়েরেবলের কাছ থেকে DbContext থেকে প্যারামিটারগুলি সহ পুরো এসকিউএল স্টেটমেন্টটি পেতে চাইনি following নিম্নলিখিত কোডটি ঠিক এটি করে। এটি গুগলের কোড স্নিপেটের সংমিশ্রণ I এটি কেবল EF6 + দিয়ে পরীক্ষা করেছে

কেবল একপাশে, এই কাজটি আমাকে যা মনে হয়েছিল তার চেয়ে অনেক বেশি সময় নিয়েছে। সত্তা ফ্রেমওয়ার্কের বিমূর্ততা কিছুটা, আইএমএইচও।

প্রথম ব্যবহার। আপনার অবশ্যই 'System.Data.Entity.dll' এ একটি স্পষ্ট উল্লেখ দরকার।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Data.Common;
using System.Data.Entity.Core.Objects;
using System.Data.Entity;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Reflection;

নিম্নলিখিত ক্লাসটি একটি আইকিউয়েরেবলকে ডেটাটেবেলে রূপান্তর করে। আপনার প্রয়োজন হিসাবে সংশোধন করুন হতে পারে:

public class EntityFrameworkCommand
{
    DbContext Context;

    string SQL;

    ObjectParameter[] Parameters;

    public EntityFrameworkCommand Initialize<T>(DbContext context, IQueryable<T> query)
    {
        Context = context;
        var dbQuery = query as DbQuery<T>;
        // get the IInternalQuery internal variable from the DbQuery object
        var iqProp = dbQuery.GetType().GetProperty("InternalQuery", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        var iq = iqProp.GetValue(dbQuery, null);
        // get the ObjectQuery internal variable from the IInternalQuery object
        var oqProp = iq.GetType().GetProperty("ObjectQuery", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        var objectQuery = oqProp.GetValue(iq, null) as ObjectQuery<T>;
        SQL = objectQuery.ToTraceString();
        Parameters = objectQuery.Parameters.ToArray();
        return this;
    }

    public DataTable GetData()
    {
        DataTable dt = new DataTable();
        var connection = Context.Database.Connection;
        var state = connection.State;
        if (!(state == ConnectionState.Open))
            connection.Open();
        using (var cmd = connection.CreateCommand())
        {
            cmd.CommandText = SQL;
            cmd.Parameters.AddRange(Parameters.Select(p => new SqlParameter("@" + p.Name, p.Value)).ToArray());
            using (var da = DbProviderFactories.GetFactory(connection).CreateDataAdapter())
            {
                da.SelectCommand = cmd;
                da.Fill(dt);
            }
        }
        if (!(state == ConnectionState.Open))
            connection.Close();
        return dt;
    }
}

ব্যবহার করতে, কেবল নীচের মত এটি কল করুন:

var context = new MyContext();
var data = ....//Query, return type can be anonymous
    .AsQueryable();
var dt = new EntityFrameworkCommand()
    .Initialize(context, data)
    .GetData();

0

সত্তা ফ্রেমওয়ার্ক 4 সমাধান

এখানে বেশিরভাগ উত্তর EF6- নির্দিষ্ট ছিল। আপনারা যারা EF4 ব্যবহার করছেন তাদের জন্য এখানে একটি।

এই পদ্ধতিটি @p__linq__0/ ইত্যাদি প্রতিস্থাপন করে । তাদের আসল মানগুলির সাথে পরামিতি, যাতে আপনি এসএসএমএসে আউটপুটটি অনুলিপি করে আটকে দিতে পারেন এবং এটি চালাতে বা এটি ডিবাগ করতে পারেন।

    /// <summary>
    /// Temporary debug function that spits out the actual SQL query LINQ is generating (with parameters)
    /// </summary>
    /// <param name="q">IQueryable object</param>
    private string Debug_GetSQLFromIQueryable<T>(IQueryable<T> q)
    {
        System.Data.Objects.ObjectQuery oq = (System.Data.Objects.ObjectQuery)q;
        var result = oq.ToTraceString();
        List<string> paramNames = new List<string>();
        List<string> paramVals = new List<string>();
        foreach (var parameter in oq.Parameters)
        {
            paramNames.Add(parameter.Name);
            paramVals.Add(parameter.Value == null ? "NULL" : ("'" + parameter.Value.ToString() + "'"));
        }
        //replace params in reverse order, otherwise @p__linq__1 incorrectly replaces @p__linq__10 for instance
        for (var i = paramNames.Count - 1; i >= 0; i--)
        {
            result = result.Replace("@" + paramNames[i], paramVals[i]);
        }
        return result;
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.