በ C # NET ውስጥ የ LINQ መጠይቆችን የማመቻቸት ዘዴዎች

መግቢያ

В ይህ ጽሑፍ አንዳንድ የማመቻቸት ዘዴዎች ተወስደዋል የ LINQ ጥያቄዎች.
እዚህ ጋር የተያያዙ አንዳንድ ተጨማሪ የኮድ ማመቻቸት አቀራረቦችን እናቀርባለን። የ LINQ ጥያቄዎች.

እንደሚታወቀው ይታወቃል LINQ(በቋንቋ የተዋሃደ መጠይቅ) የውሂብ ምንጭን ለመጠየቅ ቀላል እና ምቹ ቋንቋ ነው።

А LINQ ወደ SQL በዲቢኤምኤስ ውስጥ መረጃን ለማግኘት ቴክኖሎጂ ነው። ይህ ከውሂብ ጋር ለመስራት ኃይለኛ መሳሪያ ነው፣ መጠይቆች የሚገነቡት በአዋጅ ቋንቋ ነው፣ እሱም ወደ ሚቀየርበት የ SQL ጥያቄዎች መድረክ እና ለመፈጸም ወደ የውሂብ ጎታ አገልጋይ ተልኳል. በእኛ ሁኔታ፣ በዲቢኤምኤስ ማለታችን ነው። MS SQL አገልጋይ.

ሆኖም ግን, የ LINQ ጥያቄዎች በጥሩ ሁኔታ ወደ ተፃፉ አይለወጡም። የ SQL ጥያቄዎች፣ ልምድ ያለው DBA ከሁሉም የማመቻቸት ልዩነቶች ጋር ሊጽፍ ይችላል። የ SQL ጥያቄዎች:

  1. በጣም ጥሩ ግንኙነቶች (JOINውጤቱን በማጣራት ()የት)
  2. ግንኙነቶችን እና የቡድን ሁኔታዎችን ለመጠቀም ብዙ ልዩነቶች
  3. ሁኔታዎችን በመተካት ውስጥ ብዙ ልዩነቶች IN ላይ አይነቶችи አልገቡም, <> በርቷል አይነቶች
  4. በጊዜያዊ ሠንጠረዦች፣ CTE፣ የሠንጠረዥ ተለዋዋጮች አማካይነት ውጤቶችን መሸጎጫ
  5. የዓረፍተ ነገር አጠቃቀም (OPTION) በመመሪያዎች እና በሰንጠረዥ ፍንጮች (...)
  6. በምርጫ ወቅት ተደጋጋሚ የውሂብ ንባቦችን ለማስወገድ እንደ አንዱ ዘዴ ጠቋሚ እይታዎችን በመጠቀም

የውጤቱ ዋና የአፈፃፀም ማነቆዎች የ SQL ጥያቄዎች በማጠናቀር ጊዜ የ LINQ ጥያቄዎች ናቸው

  1. በአንድ ጥያቄ ውስጥ አጠቃላይ የውሂብ ምርጫ ዘዴን ማጠናከር
  2. ተመሳሳይ የሆኑ የኮድ ብሎኮችን ማባዛት፣ ይህም በመጨረሻ ወደ ብዙ አላስፈላጊ የውሂብ ንባብ ይመራል።
  3. የብዝሃ-ክፍል ሁኔታዎች ቡድኖች (አመክንዮአዊ “እና” እና “ወይም”) - እና и OR, ወደ ውስብስብ ሁኔታዎች በማጣመር, አመቻች, አስፈላጊ ለሆኑ መስኮች ተስማሚ ያልሆኑ ክላስተር ኢንዴክሶች ያለው, በመጨረሻ ክላስተር ኢንዴክስ ላይ መቃኘት ይጀምራል እውነታ ይመራል.ኢንዴክስ ቅኝት።) በሁኔታዎች ቡድኖች
  4. የንዑስ መጠይቆች ጥልቅ ጎጆ መተንተን በጣም ችግር ያለበት ያደርገዋል SQL መግለጫዎች እና በገንቢዎች በኩል የጥያቄ እቅድ ትንተና እና dBA

የማመቻቸት ዘዴዎች

አሁን በቀጥታ ወደ ማመቻቸት ዘዴዎች እንሂድ.

1) ተጨማሪ መረጃ ጠቋሚ

ብዙውን ጊዜ አጠቃላይ መጠይቁ በአንድ ወይም በሁለት ዋና ጠረጴዛዎች ዙሪያ (መተግበሪያዎች-ሰዎች-ኦፕሬሽኖች) እና ከመደበኛ ሁኔታዎች ስብስብ ጋር (የተዘጋ ፣ የተሰረዘ ፣ የነቃ ፣ ሁኔታ) ስለሚገነባ በዋናው ምርጫ ጠረጴዛዎች ላይ ማጣሪያዎችን ማጤን ጥሩ ነው። ለተለዩት ናሙናዎች ተስማሚ ኢንዴክሶችን መፍጠር አስፈላጊ ነው.

እነዚህ መስኮች ሲመርጡ ይህ መፍትሄ ትርጉም ያለው ነው የተመለሰውን ስብስብ ወደ መጠይቁ ይገድባል።

ለምሳሌ 500000 አፕሊኬሽኖች አሉን። ሆኖም፣ 2000 ንቁ መተግበሪያዎች ብቻ አሉ። ከዚያ በትክክል የተመረጠ ኢንዴክስ ያድነናል ኢንዴክስ ቅኝት። በትልቅ ጠረጴዛ ላይ እና በፍጥነት ባልተሰበሰበ መረጃ ጠቋሚ በኩል ውሂብን ለመምረጥ ያስችልዎታል.

እንዲሁም የጥያቄ ዕቅዶችን ለመተንተን ወይም የሥርዓት እይታ ስታቲስቲክስን ለመሰብሰብ የኢንዴክሶች እጥረት ሊታወቅ ይችላል MS SQL አገልጋይ:

  1. sys.dm_db_የጠፉ_ኢንዴክስ_ቡድኖች
  2. sys.dm_db_የጠፋ_ኢንዴክስ_ቡድን_ስታቲስቲክስ
  3. sys.dm_db_የጠፉ_ኢንዴክስ_ዝርዝሮች

ሁሉም የእይታ መረጃ ከቦታ ኢንዴክሶች በስተቀር ስለጠፉ ኢንዴክሶች መረጃ ይዟል።

ይሁን እንጂ ኢንዴክሶች እና መሸጎጫ ብዙውን ጊዜ በደንብ ያልተፃፉ ውጤቶችን የመዋጋት ዘዴዎች ናቸው የ LINQ ጥያቄዎች и የ SQL ጥያቄዎች.

ከባድ የህይወት ልምምድ እንደሚያሳየው, ብዙውን ጊዜ ለንግድ ስራ ባህሪያት በተወሰኑ የግዜ ገደቦች መተግበሩ አስፈላጊ ነው. እና ስለዚህ፣ ከባድ ጥያቄዎች ብዙ ጊዜ በመሸጎጥ ወደ ዳራ ይተላለፋሉ።

ተጠቃሚው ሁልጊዜ የቅርብ ጊዜውን መረጃ ስለማይፈልግ እና የተጠቃሚ በይነገጽ ተቀባይነት ያለው ምላሽ ደረጃ ስላለ ይህ በከፊል ትክክል ነው።

ይህ አካሄድ የንግድ ፍላጎቶችን ለመፍታት ያስችላል፣ነገር ግን በመጨረሻ ለችግሮች መፍትሄዎችን በማዘግየት የመረጃ ስርዓቱን አፈጻጸም ይቀንሳል።

በተጨማሪም ለማከል አስፈላጊ የሆኑትን ኢንዴክሶች በመፈለግ ሂደት ውስጥ, ጥቆማዎችን ማስታወስ ጠቃሚ ነው ኤም.ኤስ.ኤስ.ኤል. በሚከተሉት ሁኔታዎች ውስጥ ጨምሮ ማመቻቸት ትክክል ላይሆን ይችላል፡

  1. ተመሳሳይ የመስክ ስብስብ ያላቸው ኢንዴክሶች ካሉ
  2. በሠንጠረዡ ውስጥ ያሉት መስኮች በመረጃ ጠቋሚ ገደቦች ምክንያት መጠቆም ካልቻሉ (በበለጠ ዝርዝር ውስጥ ተብራርቷል እዚህ).

2) ባህሪያትን ወደ አንድ አዲስ ባህሪ ማዋሃድ

አንዳንድ ጊዜ ከአንድ ሠንጠረዥ የተወሰኑ መስኮች, ለቡድን ሁኔታዎች መሰረት ሆነው ያገለግላሉ, አንድ አዲስ መስክ በማስተዋወቅ ሊተኩ ይችላሉ.

ይህ በተለይ በዓይነት ቢት ወይም ኢንቲጀር ለሆኑ የሁኔታ መስኮች እውነት ነው።

ለምሳሌ:

ተዘግቷል = 0 እና ተሰርዟል = 0 እና ነቅቷል = 0 ተተክቷል ሁኔታ = 1.

እነዚህ ሁኔታዎች በሰንጠረዡ ውስጥ መሞላታቸውን ለማረጋገጥ የኢንቲጀር የኹናቴ ባህሪ የሚተዋወቀው እዚህ ላይ ነው። በመቀጠል፣ ይህ አዲስ ባህሪ መረጃ ጠቋሚ ነው።

ይህ ለአፈፃፀም ችግር መሰረታዊ መፍትሄ ነው, ምክንያቱም ያለአስፈላጊ ስሌቶች መረጃን ስለምንደርስ ነው.

3) የአመለካከት ቁሳቁስ

በሚያሳዝን ሁኔታ ውስጥ የ LINQ ጥያቄዎች ጊዜያዊ ሠንጠረዦች፣ CTEs፣ እና የሠንጠረዥ ተለዋዋጮች በቀጥታ ጥቅም ላይ ሊውሉ አይችሉም።

ሆኖም ግን, ለዚህ ጉዳይ ለማመቻቸት ሌላ መንገድ አለ - የተጠቆሙ እይታዎች.

ሁኔታ ቡድን (ከላይ ካለው ምሳሌ) ተዘግቷል = 0 እና ተሰርዟል = 0 እና ነቅቷል = 0 (ወይም ሌሎች ተመሳሳይ ሁኔታዎች ስብስብ) ከትልቅ ስብስብ ትንሽ ቁራጭ ውሂብ በመሸጎጥ በመረጃ ጠቋሚ እይታ ለመጠቀም ጥሩ አማራጭ ይሆናል።

ግን እይታን በሚተገበሩበት ጊዜ በርካታ ገደቦች አሉ-

  1. ንዑስ መጠይቆችን ፣ አንቀጾችን መጠቀም አይነቶች በመጠቀም መተካት አለበት JOIN
  2. አረፍተ ነገሮችን መጠቀም አይችሉም ዩኒየን, ህብረት, በስተቀር, ተገናኝ
  3. የሰንጠረዥ ፍንጮችን እና ሐረጎችን መጠቀም አይችሉም OPTION
  4. ከዑደት ጋር የመሥራት ዕድል የለም
  5. ከተለያዩ ሰንጠረዦች በአንድ እይታ ውስጥ መረጃን ማሳየት አይቻልም

ኢንዴክስ የተደረገ እይታን መጠቀም እውነተኛው ጥቅም ሊገኝ የሚችለው በትክክል በማውጣት ብቻ መሆኑን ማስታወስ አስፈላጊ ነው.

ነገር ግን እይታን በሚጠሩበት ጊዜ እነዚህ ኢንዴክሶች ጥቅም ላይ መዋል አይችሉም፣ እና እነሱን በግልፅ ለመጠቀም፣ መጥቀስ አለብዎት ከ(NOEXPAND) ጋር.

ከውስጥ ጀምሮ የ LINQ ጥያቄዎች የሠንጠረዥ ፍንጮችን ለመግለጽ የማይቻል ነው, ስለዚህ ሌላ ውክልና መፍጠር አለብዎት - የሚከተለው ቅጽ "መጠቅለያ":

CREATE VIEW ИМЯ_представления AS SELECT * FROM MAT_VIEW WITH (NOEXPAND);

4) የጠረጴዛ ተግባራትን መጠቀም

ብዙውን ጊዜ ውስጥ የ LINQ ጥያቄዎች ውስብስብ መዋቅር ያላቸውን እይታዎች በመጠቀም ትላልቅ የንዑስ መጠይቆች ወይም ብሎኮች የመጨረሻ መጠይቅ በጣም ውስብስብ እና ዝቅተኛ የአፈፃፀም መዋቅር ይመሰርታሉ።

በ ውስጥ የጠረጴዛ ተግባራትን የመጠቀም ቁልፍ ጥቅሞች የ LINQ ጥያቄዎች:

  1. እንደ እይታዎች ፣ እንደ ዕቃ የመጠቀም እና የመገለጽ ችሎታ ፣ ግን የግቤት መለኪያዎችን ስብስብ ማለፍ ይችላሉ-
    ከተግባር(@param1፣ @param2 ...)
    በውጤቱም, ተለዋዋጭ የውሂብ ናሙና ማግኘት ይቻላል
  2. የሰንጠረዥ ተግባርን በሚጠቀሙበት ጊዜ፣ ከላይ በተገለጹት የተጠቆሙ አመለካከቶች ውስጥ እንደዚህ ያሉ ጠንካራ ገደቦች የሉም።
    1. የሠንጠረዥ ፍንጮች
      በኩል LINQ በመጠየቅ ጊዜ የትኛዎቹ ኢንዴክሶች ጥቅም ላይ መዋል እንዳለባቸው መግለጽ እና የውሂብ ማግለል ደረጃን መወሰን አይችሉም።
      ግን ተግባሩ እነዚህ ችሎታዎች አሉት.
      በተግባሩ ፣ ከመረጃ ጠቋሚዎች እና ከመረጃ ማግለል ደረጃዎች ጋር አብሮ ለመስራት ህጎች የሚገለጹበት ትክክለኛ የሆነ የማያቋርጥ የአፈፃፀም መጠይቅ ዕቅድ ማግኘት ይችላሉ።
    2. ተግባሩን መጠቀም ከመረጃ ጠቋሚ እይታዎች ጋር ሲነጻጸር የሚከተሉትን ለማግኘት ያስችላል፡-
      • ውስብስብ የውሂብ ናሙና አመክንዮ (ሉፕ መጠቀምም ቢሆን)
      • ከተለያዩ ሰንጠረዦች ውሂብ በማምጣት ላይ
      • አጠቃቀም ዩኒየን и አይነቶች

  3. ቅናሽ OPTION የኮንስትራክሽን ቁጥጥርን መስጠት ሲያስፈልገን በጣም ጠቃሚ ነው። አማራጭ(MAXDOP N)፣ የጥያቄው አፈፃፀም እቅድ ቅደም ተከተል። ለምሳሌ:
    • የጥያቄ እቅዱን በግዳጅ እንደገና ለመፍጠር መግለጽ ይችላሉ። አማራጭ (እንደገና መሰብሰብ)
    • በጥያቄው ውስጥ የተገለጸውን የመቀላቀል ትእዛዝ እንዲጠቀም የመጠይቁ እቅዱን ማስገደድ ወይም አለመገደዱን መግለጽ ይችላሉ። አማራጭ (የግዳጅ ትዕዛዝ)

    ስለ ተጨማሪ ዝርዝሮች OPTION ተገል describedል እዚህ.

  4. በጣም ጠባብ እና በጣም አስፈላጊ የሆነውን የውሂብ ቁራጭ በመጠቀም፡-
    ትላልቅ የውሂብ ስብስቦችን በመሸጎጫዎች ውስጥ ማከማቸት አያስፈልግም (እንደ መረጃ ጠቋሚ እይታዎች ሁኔታ), ከነሱ አሁንም ውሂቡን በመለኪያ ማጣራት ያስፈልግዎታል.
    ለምሳሌ, ማጣሪያው ጠረጴዛ አለ የት ሶስት መስኮች ጥቅም ላይ ይውላሉ (a, b, c).

    በተለምዶ፣ ሁሉም ጥያቄዎች ቋሚ ሁኔታ አላቸው። a = 0 እና b = 0.

    ሆኖም የሜዳው ጥያቄ c የበለጠ ተለዋዋጭ.

    ሁኔታውን ይፍቀዱ a = 0 እና b = 0 የሚፈለገውን የውጤት ስብስብ በሺዎች የሚቆጠሩ መዝገቦችን ለመገደብ በእውነት ይረዳናል, ነገር ግን ሁኔታው ​​ላይ с ምርጫውን ወደ መቶ መዝገቦች ያጠባል።

    እዚህ የጠረጴዛው ተግባር የተሻለ አማራጭ ሊሆን ይችላል.

    እንዲሁም የሠንጠረዥ ተግባር የበለጠ ሊተነበይ የሚችል እና በአፈፃፀም ጊዜ ውስጥ ወጥነት ያለው ነው.

ምሳሌዎች

የጥያቄዎች ዳታቤዝ እንደ ምሳሌ በመጠቀም አንድ ምሳሌ ትግበራን እንመልከት።

ጥያቄ አለ። ይምረጡበርካታ ሠንጠረዦችን አጣምሮ አንድ እይታን የሚጠቀም (OperativeQuestions)፣ ቁርኝነቱ በኢሜል የሚረጋገጥበት አይነቶች) ወደ “ንቁ መጠይቆች” ([OperativeQuestions])፡-

ጥያቄ ቁጥር 1

(@p__linq__0 nvarchar(4000))SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Join2].[Object_Id] AS [Object_Id],
[Join2].[ObjectType_Id] AS [ObjectType_Id],
[Join2].[Name] AS [Name],
[Join2].[ExternalId] AS [ExternalId]
FROM [dbo].[Questions] AS [Extent1]
INNER JOIN (SELECT [Extent2].[Object_Id] AS [Object_Id],
[Extent2].[Question_Id] AS [Question_Id], [Extent3].[ExternalId] AS [ExternalId],
[Extent3].[ObjectType_Id] AS [ObjectType_Id], [Extent4].[Name] AS [Name]
FROM [dbo].[ObjectQuestions] AS [Extent2]
INNER JOIN [dbo].[Objects] AS [Extent3] ON [Extent2].[Object_Id] = [Extent3].[Id]
LEFT OUTER JOIN [dbo].[ObjectTypes] AS [Extent4] 
ON [Extent3].[ObjectType_Id] = [Extent4].[Id] ) AS [Join2] 
ON [Extent1].[Id] = [Join2].[Question_Id]
WHERE ([Extent1].[AnswerId] IS NULL) AND (0 = [Extent1].[Exp]) AND ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[OperativeQuestions] AS [Extent5]
WHERE (([Extent5].[Email] = @p__linq__0) OR (([Extent5].[Email] IS NULL) 
AND (@p__linq__0 IS NULL))) AND ([Extent5].[Id] = [Extent1].[Id])
));

እይታው በጣም የተወሳሰበ መዋቅር አለው፡ ንዑስ መጋጠሚያዎች አሉት እና መደርደርን ይጠቀማል DISTINCTበአጠቃላይ ፍትሃዊ ሀብትን የሚጠይቅ ክዋኔ ነው።

ከOperativeQuestions የተወሰደ ናሙና ወደ አስር ሺህ መዝገቦች ነው።

የዚህ መጠይቅ ዋናው ችግር ከውጪው መጠይቅ ላሉ መዝገቦች፣ በ[OperativeQuestions] እይታ ላይ የውስጥ ንዑስ ጥያቄ ይፈጸማል፣ ይህም ለ [ኢሜል] = @p__linq__0 የውጤት ምርጫን እንድንገድብ ያስችለናል (በ በኩል) አይነቶች) በመቶዎች የሚቆጠሩ መዝገቦች.

እና ንዑስ መጠይቁ መዝገቦቹን አንድ ጊዜ በ [ኢሜል] = @p__linq__0 ማስላት ያለበት ሊመስል ይችላል ከዚያም እነዚህ ሁለት መቶ መዛግብት በ Id ከጥያቄዎች ጋር መያያዝ አለባቸው እና መጠይቁ ፈጣን ይሆናል።

በእውነቱ፣ የሁሉም ሠንጠረዦች ተከታታይ ግንኙነት አለ፡ የመታወቂያ ጥያቄዎችን ደብዳቤ ከኦፕሬቲቭ ጥያቄዎች ጋር መፈተሽ እና በኢሜል ማጣራት።

በእርግጥ፣ ጥያቄው በአስር ሺዎች ከሚቆጠሩ የOperativeQuestions መዝገቦች ጋር ይሰራል፣ነገር ግን የፍላጎት ውሂብ በኢሜል ብቻ ነው የሚያስፈልገው።

ተግባራዊ ጥያቄዎች እይታ ጽሑፍ፡-

ጥያቄ ቁጥር 2

 
CREATE VIEW [dbo].[OperativeQuestions]
AS
SELECT DISTINCT Q.Id, USR.email AS Email
FROM            [dbo].Questions AS Q INNER JOIN
                         [dbo].ProcessUserAccesses AS BPU ON BPU.ProcessId = CQ.Process_Id 
OUTER APPLY
                     (SELECT   1 AS HasNoObjects
                      WHERE   NOT EXISTS
                                    (SELECT   1
                                     FROM     [dbo].ObjectUserAccesses AS BOU
                                     WHERE   BOU.ProcessUserAccessId = BPU.[Id] AND BOU.[To] IS NULL)
) AS BO INNER JOIN
                         [dbo].Users AS USR ON USR.Id = BPU.UserId
WHERE        CQ.[Exp] = 0 AND CQ.AnswerId IS NULL AND BPU.[To] IS NULL 
AND (BO.HasNoObjects = 1 OR
              EXISTS (SELECT   1
                           FROM   [dbo].ObjectUserAccesses AS BOU INNER JOIN
                                      [dbo].ObjectQuestions AS QBO 
                                                  ON QBO.[Object_Id] =BOU.ObjectId
                               WHERE  BOU.ProcessUserAccessId = BPU.Id 
                               AND BOU.[To] IS NULL AND QBO.Question_Id = CQ.Id));

የመጀመሪያ እይታ ካርታ በDbContext (EF Core 2)

public class QuestionsDbContext : DbContext
{
    //...
    public DbQuery<OperativeQuestion> OperativeQuestions { get; set; }
    //...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Query<OperativeQuestion>().ToView("OperativeQuestions");
    }
}

የመጀመሪያ የ LINQ ጥያቄ

var businessObjectsData = await context
    .OperativeQuestions
    .Where(x => x.Email == Email)
    .Include(x => x.Question)
    .Select(x => x.Question)
    .SelectMany(x => x.ObjectQuestions,
                (x, bo) => new
                {
                    Id = x.Id,
                    ObjectId = bo.Object.Id,
                    ObjectTypeId = bo.Object.ObjectType.Id,
                    ObjectTypeName = bo.Object.ObjectType.Name,
                    ObjectExternalId = bo.Object.ExternalId
                })
    .ToListAsync();

በዚህ ጉዳይ ላይ የመሰረተ ልማት ለውጦች ሳይኖሩበት የተለየ ሠንጠረዥ ሳያስገቡ ዝግጁ የሆኑ ውጤቶች (“ንቁ መጠይቆች”) ሳናቀርብ መፍትሄውን በመረጃ መሙላት እና ወቅታዊ ለማድረግ እያሰብን ነው። .

ምንም እንኳን ይህ ጥሩ መፍትሄ ቢሆንም, ይህንን ችግር ለማመቻቸት ሌላ አማራጭ አለ.

ዋናው አላማ ግቤቶችን በ[ኢሜል] = @p__linq__0 ከኦፕሬቲቭ ጥያቄዎች እይታ መሸጎጥ ነው።

የሰንጠረዡን ተግባር [dbo] አስተዋውቁ።[OperativeQuestionsUserMail] ወደ ዳታቤዝ።

ኢሜልን እንደ የግቤት መለኪያ በመላክ የእሴቶችን ሰንጠረዥ እንመልሳለን፡-

ጥያቄ ቁጥር 3


CREATE FUNCTION [dbo].[OperativeQuestionsUserMail]
(
    @Email  nvarchar(4000)
)
RETURNS
@tbl TABLE
(
    [Id]           uniqueidentifier,
    [Email]      nvarchar(4000)
)
AS
BEGIN
        INSERT INTO @tbl ([Id], [Email])
        SELECT Id, @Email
        FROM [OperativeQuestions]  AS [x] WHERE [x].[Email] = @Email;
     
    RETURN;
END

ይህ አስቀድሞ የተወሰነ የውሂብ መዋቅር ያለው የእሴቶችን ሰንጠረዥ ይመልሳል።

ወደ OperativeQuestionsUserMail የሚቀርቡ መጠይቆች ጥሩ እንዲሆኑ እና ጥሩ የመጠይቅ ዕቅዶች እንዲኖራቸው፣ ጥብቅ መዋቅር ያስፈልጋል፣ እና አይደለም ሠንጠረዥን እንደ መመለሻ ይመልሳል...

በዚህ አጋጣሚ፣ የሚፈለገው መጠይቅ 1 ወደ መጠይቅ 4 ይቀየራል።

ጥያቄ ቁጥር 4

(@p__linq__0 nvarchar(4000))SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Join2].[Object_Id] AS [Object_Id],
[Join2].[ObjectType_Id] AS [ObjectType_Id],
[Join2].[Name] AS [Name],
[Join2].[ExternalId] AS [ExternalId]
FROM (
    SELECT Id, Email FROM [dbo].[OperativeQuestionsUserMail] (@p__linq__0)
) AS [Extent0]
INNER JOIN [dbo].[Questions] AS [Extent1] ON([Extent0].Id=[Extent1].Id)
INNER JOIN (SELECT [Extent2].[Object_Id] AS [Object_Id], [Extent2].[Question_Id] AS [Question_Id], [Extent3].[ExternalId] AS [ExternalId], [Extent3].[ObjectType_Id] AS [ObjectType_Id], [Extent4].[Name] AS [Name]
FROM [dbo].[ObjectQuestions] AS [Extent2]
INNER JOIN [dbo].[Objects] AS [Extent3] ON [Extent2].[Object_Id] = [Extent3].[Id]
LEFT OUTER JOIN [dbo].[ObjectTypes] AS [Extent4] 
ON [Extent3].[ObjectType_Id] = [Extent4].[Id] ) AS [Join2] 
ON [Extent1].[Id] = [Join2].[Question_Id]
WHERE ([Extent1].[AnswerId] IS NULL) AND (0 = [Extent1].[Exp]);

በDbContext (ኢኤፍ ኮር 2) ውስጥ ያሉ የካርታ ስራዎች እይታዎች እና ተግባራት

public class QuestionsDbContext : DbContext
{
    //...
    public DbQuery<OperativeQuestion> OperativeQuestions { get; set; }
    //...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Query<OperativeQuestion>().ToView("OperativeQuestions");
    }
}
 
public static class FromSqlQueries
{
    public static IQueryable<OperativeQuestion> GetByUserEmail(this DbQuery<OperativeQuestion> source, string Email)
        => source.FromSql($"SELECT Id, Email FROM [dbo].[OperativeQuestionsUserMail] ({Email})");
}

የመጨረሻ የ LINQ ጥያቄ

var businessObjectsData = await context
    .OperativeQuestions
    .GetByUserEmail(Email)
    .Include(x => x.Question)
    .Select(x => x.Question)
    .SelectMany(x => x.ObjectQuestions,
                (x, bo) => new
                {
                    Id = x.Id,
                    ObjectId = bo.Object.Id,
                    ObjectTypeId = bo.Object.ObjectType.Id,
                    ObjectTypeName = bo.Object.ObjectType.Name,
                    ObjectExternalId = bo.Object.ExternalId
                })
    .ToListAsync();

የማስፈጸሚያ ጊዜ ቅደም ተከተል ከ200-800 ms, ወደ 2-20 ms, ወዘተ, ማለትም በአስር እጥፍ ፈጣን ቀንሷል.

በአማካኝ ከወሰድነው በ350 ms ምትክ 8 ms አግኝተናል።

ከግልጽ ጥቅሞች በተጨማሪ እናገኛለን-

  1. አጠቃላይ የንባብ ጭነት መቀነስ ፣
  2. የመከልከል እድልን በከፍተኛ ሁኔታ መቀነስ
  3. አማካይ የማገጃ ጊዜን ወደ ተቀባይነት ያላቸው እሴቶች መቀነስ

መደምደሚያ

የውሂብ ጎታ ጥሪዎችን ማመቻቸት እና ማስተካከል ኤም.ኤስ.ኤስ.ኤል. በኩል LINQ ሊፈታ የሚችል ችግር ነው።

በዚህ ሥራ ውስጥ ትኩረት እና ወጥነት በጣም አስፈላጊ ናቸው.

በሂደቱ መጀመሪያ ላይ:

  1. ጥያቄው የሚሰራበትን ውሂብ (እሴቶች, የተመረጡ የውሂብ አይነቶች) ማረጋገጥ አስፈላጊ ነው.
  2. የዚህን ውሂብ ትክክለኛ መረጃ ጠቋሚ ያካሂዱ
  3. በጠረጴዛዎች መካከል የመቀላቀል ሁኔታዎችን ትክክለኛነት ያረጋግጡ

የሚቀጥለው የማመቻቸት ድግግሞሽ ያሳያል፡-

  1. የጥያቄውን መሠረት እና ዋናውን የጥያቄ ማጣሪያ ይገልፃል።
  2. ተመሳሳይ መጠይቅ ብሎኮችን መድገም እና የሁኔታዎች መገናኛን መተንተን
  3. በኤስኤምኤስ ወይም በሌላ GUI ለ SQL Server እራሱን ያመቻቻል የ SQL ጥያቄ (መካከለኛ የውሂብ ማከማቻ መመደብ፣ ይህንን ማከማቻ በመጠቀም የተገኘውን መጠይቅ መገንባት (በርካታ ሊኖሩ ይችላሉ))
  4. በመጨረሻው ደረጃ ፣ ውጤቱን መሠረት በማድረግ የ SQL ጥያቄ, መዋቅሩ እንደገና እየተገነባ ነው የ LINQ ጥያቄ

የተገኘው የ LINQ ጥያቄ በመዋቅር ውስጥ ከተመረጡት ጋር ተመሳሳይ መሆን አለበት የ SQL ጥያቄ ከ ነጥብ 3.

ምስጋናዎች

ለባልደረባዎች በጣም አመሰግናለሁ jobgemws и አሌክስ_ኦዘር ከኩባንያው Fortis ይህንን ቁሳቁስ ለማዘጋጀት እርዳታ ለማግኘት.

ምንጭ: hab.com

አስተያየት ያክሉ