সংস্থাগুলিতে লিনকিউ 'সিস্টেম.স্ট্রিং টুস্ট্রিং ()' পদ্ধতিটি স্বীকৃতি দেয় না এবং এই পদ্ধতিটি কোনও স্টোর এক্সপ্রেশনে অনুবাদ করা যায় না cannot


126

আমি একটি mysql সার্ভার থেকে একটি এসকিএল সার্ভারে কিছু জিনিস স্থানান্তরিত করছি তবে এই কোডটি কীভাবে কাজ করা যায় তা আমি বুঝতে পারি না:

using (var context = new Context())
{
    ...

    foreach (var item in collection)
    {
        IQueryable<entity> pages = from p in context.pages
                                   where  p.Serial == item.Key.ToString()
                                   select p;
        foreach (var page in pages)
        {
            DataManager.AddPageToDocument(page, item.Value);
        }
    }

    Console.WriteLine("Done!");
    Console.Read();
}

এটি যখন দ্বিতীয়টিতে প্রবেশ করে তখন এটি foreach (var page in pages)ব্যতিক্রম ছুঁড়ে ফেলে বলে:

সংস্থাগুলিতে লিনকিউ 'সিস্টেম.স্ট্রিং টুস্ট্রিং ()' পদ্ধতিটি স্বীকৃতি দেয় না এবং এই পদ্ধতির কোনও স্টোর এক্সপ্রেশনে অনুবাদ করা যায় না।

কেউ জানেন কেন এমন হয়?


উত্তর:


134

কেবল স্ট্রিংটিকে একটি অস্থায়ী ভেরিয়েবলে সংরক্ষণ করুন এবং তারপরে আপনার অভিব্যক্তিতে এটি ব্যবহার করুন:

var strItem = item.Key.ToString();

IQueryable<entity> pages = from p in context.pages
                           where  p.Serial == strItem
                           select p;

সমস্যা দেখা দেয় কারণ ToString()সত্যই মৃত্যুদন্ড কার্যকর করা হয়নি, এটি একটি মেথডগ্রুপে রূপান্তরিত হয় এবং তারপরে পার্স করে এসকিউএল অনুবাদ করা হয়। যেহেতু কোনও ToString()সমতুল্য নয়, ভাবটি ব্যর্থ হয়।

বিঃদ্রঃ:

নিশ্চিত হয়ে নিন যে আপনি পরে যুক্ত হওয়া সহায়ক শ্রেণীর বিষয়েও অ্যালেক্সের উত্তরটি পরীক্ষা করে দেখেছেনSqlFunctions । অনেক ক্ষেত্রে এটি অস্থায়ী পরিবর্তনশীলের প্রয়োজনকে দূর করতে পারে।


14
আমার টসস্ট্রিং () সাম্যের বাম-পাশে প্রয়োগ করা হলে কী হবে? egpSerial.ToString () = আইটেম।
ডটনেট

3
@ ডটনেট এটি এখনও ব্যর্থ হবে কারণ পুরো জিনিসটি একটি অভিব্যক্তিতে পরিণত হয়েছে, যা সত্তা ফ্রেমওয়ার্ক বৈধ এসকিউএল রূপান্তরিত করার চেষ্টা করে। কিছু পদ্ধতি রয়েছে যা এটি পরিচালনা করতে জানে তবে সেগুলির মধ্যে ToString()একটিও নয়।
জোশ

7
@ জোশ: আমি বুঝতে পারি যে এটি ব্যর্থ হবে। আমি যা চেয়েছিলাম তা হল সেই দৃশ্যের একটি সমাধান, কারণ উপরের সমাধানটি অবশ্যই সেখানে প্রয়োগ করা যায় না।
ডটনেট

3
@ জোশ: আমি এরকম একটি দৃশ্যের সাথে লড়াই করছি। বলুন আমার অর্ডার নাম্বার কলামটি অন্তঃসত্ত্বা, তবে আমার ব্যবহারকারী তার টাইপ করার সাথে সাথে অর্ডার নাম্বারগুলির তালিকা ফিল্টার করতে সক্ষম হতে চান search তিনি যদি অনুসন্ধান বাক্সে 143 টাইপ করেন তবে তিনি কেবলমাত্র সেই রেকর্ডগুলি চান যা একটি অর্ডার নাম্বারের মতো '% 143%' রয়েছে । অর্ডারনম্বার কলামটি অর্জন করার জন্য আমার কি টসস্ট্রিং () করার দরকার নেই?
ডটনেট

5
@ ডটনেট এটি সেই পরিস্থিতিতে একটি যেখানে ওআরএম এর মুখের উপর পড়ে। আমি মনে করি যে এই পরিস্থিতিতেগুলি সোজা এসকিউএল এর মাধ্যমে ExecuteQueryবা সত্তা এসকিউএল ব্যবহার করে নীচে ObjectQuery<T>
জোশ

69

অন্যরা যেমন উত্তর দিয়েছে, এটি বিরতি কারণ .ToString ডেটাবেস মধ্যে প্রাসঙ্গিক এসকিউএল অনুবাদ করতে ব্যর্থ।

যাইহোক, মাইক্রোসফ্ট এসকিএলফিউশনগুলি ক্লাস সরবরাহ করে যা এমন পদ্ধতির সংগ্রহ যা এই জাতীয় পরিস্থিতিতে ব্যবহার করা যায়।

এই ক্ষেত্রে, আপনি এখানে যা খুঁজছেন তা হ'ল এসকিএলফিউশনস St স্ট্রিংকনভার্ট :

from p in context.pages
where  p.Serial == SqlFunctions.StringConvert((double)item.Key.Id)
select p;

অস্থায়ী ভেরিয়েবলগুলির সাথে সমাধানটি যে কোনও কারণেই পছন্দসই নয় Good

এসকিএলফিউনেশনের অনুরূপ আপনারও সত্তা ফাংশন রয়েছে (EF6 দ্বারা DbFunitions দ্বারা অপ্রচলিত ) যা বিভিন্ন উত্সের ফাংশন সরবরাহ করে যা ডেটা সোর্স অজ্ঞোস্টিক ( যেমন এসকিউএল-তে সীমাবদ্ধ নয়)।


4
তারা .NET 4 এ ফিরে এসকিএলএফুনিউশন ক্লাস যুক্ত করেছে এবং আমি কেবল এটি সম্পর্কে শিখছি? দুর্দান্ত সন্ধান।
জেমস স্কেম্প

24

সমস্যাটি হ'ল আপনি টিনস্ট্রিংকে একটি লিনকিউ থেকে সত্তা কোয়েরিতে জিজ্ঞাসা করছেন। তার মানে পার্সার তোস্ট্রিং কলটিকে তার সমতুল্য এসকিউএল (যা সম্ভব নয় ... সুতরাং ব্যতিক্রম) তে রূপান্তর করার চেষ্টা করছে।

আপনাকে যা করতে হবে তা হল টুস্ট্রিং কলকে একটি পৃথক লাইনে স্থানান্তরিত করতে হবে:

var keyString = item.Key.ToString();

var pages = from p in context.entities
            where p.Serial == keyString
            select p;

9

একই সমস্যা ছিল। সত্তা সংগ্রহের ক্ষেত্রে টোলিস্ট () কে কল করে এবং তালিকাটি অনুসন্ধান করে সমাধান করেছেন। সংগ্রহটি ছোট হলে এটি একটি বিকল্প।

IQueryable<entity> pages = context.pages.ToList().Where(p=>p.serial == item.Key.ToString())

আশাকরি এটা সাহায্য করবে.


42
দয়া করে নোট করুন এটি ডাটাবেস থেকে সমস্ত পৃষ্ঠা সত্তা পুনরুদ্ধার করবে এবং ডিবি এর পরিবর্তে ক্লায়েন্টের পাশে ফিল্টারিং করবে .. সাধারণত কোনও ভাল জিনিস নয়।
ল্যাম্বিনেটর

3
এটি সত্য যে কোনও টেবিলের একাধিক রেকর্ড রয়েছে, যার অর্থ অস্তিত্বের সমস্ত সারণী :-) এর জন্য এই পদ্ধতিটি অদক্ষ হবে। যাইহোক, এই উত্তরটি আজ আমাকে সাহায্য করেছিল কারণ আমি একটি করছিলাম। নির্বাচন প্রক্ষেপণে টসস্ট্রিং () এত কল করা অন্তর্ভুক্ত ছিল handToList () হাতের আগে আমার জন্য কোনও পারফরম্যান্স পেনাল্টি ছিল না oToList () আমাকে .ToString () ব্যবহারের অনুমতি দিয়েছে) ফর্ম্যাটিং এবং আমার .সত্যি বিবৃতি নির্বাচন করুন ...
নাথান প্রথর

6

এটি এটির মতো পরিবর্তন করুন এবং এটি কাজ করা উচিত:

var key = item.Key.ToString();
IQueryable<entity> pages = from p in context.pages
                           where  p.Serial == key
                           select p;

লাইনকিউ ক্যোয়ারী ঘোষিত হওয়া লাইনে ব্যতিক্রমটি ছুঁড়ে ফেলার কারণ না থাকলেও এর লাইনে foreachহ'ল পিছিয়ে দেওয়া কার্যকরকরণ বৈশিষ্ট্য, যেমন আপনি ফলাফলটি অ্যাক্সেস করার চেষ্টা না করা অবধি লিনকুই কোয়েরি কার্যকর করা হয় না। এবং এটি foreachআগে ঘটেছিল এবং না ঘটে ।


6

টেবিলটি এতে কাস্ট করুন Enumerable, তারপরে আপনি ToString()অভ্যন্তরীণ পদ্ধতি ব্যবহার করে লিনকিউ পদ্ধতিতে কল করবেন :

    var example = contex.table_name.AsEnumerable()
.Select(x => new {Date = x.date.ToString("M/d/yyyy")...)

তবে আপনি যখন কল করছেন AsEnumerableবা ToListপদ্ধতিগুলি কল করবেন তখন সাবধান থাকবেন কারণ আপনি এই পদ্ধতির আগে সমস্ত সত্তা থেকে সমস্ত ডেটা অনুরোধ করবেন। আমার ক্ষেত্রে উপরে আমি সমস্ত table_nameঅনুরোধটি একটি অনুরোধে পড়েছি ।


5
: সাধারনত একটি ভাল পছন্দ না হয়, তাহলে .AsEnumerable () সমস্ত ডেটা মেমরি এখানে রাখুন, আপনি এটি সম্পর্কে আরো দেখতে পারেন stackoverflow.com/questions/3311244/...
kavain

5

সত্তা ফ্রেমওয়ার্ক সংস্করণে আপগ্রেড করা আমার পক্ষে কাজ করেছে ..২.০

আমি এর আগে সংস্করণ 6.0.0 এ ছিলাম।

আশাকরি এটা সাহায্য করবে,


1

এমভিসিতে, ধরে নিন যে আপনি আপনার প্রয়োজনীয়তা বা তথ্যের উপর ভিত্তি করে রেকর্ড (গুলি) অনুসন্ধান করছেন। এটি সঠিকভাবে কাজ করছে।

[HttpPost]
[ActionName("Index")]
public ActionResult SearchRecord(FormCollection formcollection)
{       
    EmployeeContext employeeContext = new EmployeeContext();

    string searchby=formcollection["SearchBy"];
    string value=formcollection["Value"];

    if (formcollection["SearchBy"] == "Gender")
    {
        List<MvcApplication1.Models.Employee> emplist = employeeContext.Employees.Where(x => x.Gender == value).ToList();
        return View("Index", emplist);
    }
    else
    {
        List<MvcApplication1.Models.Employee> emplist = employeeContext.Employees.Where(x => x.Name == value).ToList();
        return View("Index", emplist);
    }         
}

2
উন্নত অনুশীলনের জন্য, বা উত্পাদন ধরণের কোডের জন্য, আপনার সর্বদা ডেটাবেস ইভেন্টগুলি কোনও পরিষেবা স্তর বা ডেটা স্তরে থাকা উচিত এবং সরাসরি ক্রিয়ায় নয়।
TGarrett

0

আপনি যদি সত্যিই ToStringআপনার ক্যোয়ারির ভিতরে টাইপ করতে চান তবে আপনি একটি অভিব্যক্তি ট্রি ভিজিটর লিখতে পারেন যা উপযুক্ত ফাংশনেToString একটি কলStringConvert দিয়ে কলটি পুনরায় লিখে :

using System.Linq;
using System.Data.Entity.SqlServer;
using System.Linq.Expressions;
using static System.Linq.Expressions.Expression;
using System;

namespace ToStringRewriting {
    class ToStringRewriter : ExpressionVisitor {
        static MethodInfo stringConvertMethodInfo = typeof(SqlFunctions).GetMethods()
                 .Single(x => x.Name == "StringConvert" && x.GetParameters()[0].ParameterType == typeof(decimal?));

        protected override Expression VisitMethodCall(MethodCallExpression node) {
            var method = node.Method;
            if (method.Name=="ToString") {
                if (node.Object.GetType() == typeof(string)) { return node.Object; }
                node = Call(stringConvertMethodInfo, Convert(node.Object, typeof(decimal?));
            }
            return base.VisitMethodCall(node);
        }
    }
    class Person {
        string Name { get; set; }
        long SocialSecurityNumber { get; set; }
    }
    class Program {
        void Main() {
            Expression<Func<Person, Boolean>> expr = x => x.ToString().Length > 1;
            var rewriter = new ToStringRewriter();
            var finalExpression = rewriter.Visit(expr);
            var dcx = new MyDataContext();
            var query = dcx.Persons.Where(finalExpression);

        }
    }
}

ফার্স্টআরডিফল্ট ব্যবহার করা উচিত এবং কেবল প্রথম নয় ... যদি এটি একটি প্রাথমিক কী হয়, তবে এটি ব্যবহার করুন, এটি আরও ভাল করে তোলে।
TGarrett

@TGarrett এখানে শুধুমাত্র ব্যবহারের Firstফলাফল GetMethods()যা ফলাফল আসে MethodInfo[]। আফাইক, এর MethodInfo[]কোনও Findপদ্ধতি নেই বা এ জাতীয় সম্প্রসারণ পদ্ধতিও নেই। তবে আমার সত্যই ব্যবহার করা উচিত Singleকারণ প্রতিবিম্বের মাধ্যমে এই পদ্ধতিটি সন্ধান করা হচ্ছে এবং উপযুক্ত পদ্ধতিটি সমাধান না করতে পারলে একটি সংকলন-সময় ত্রুটি হবে না।
জেভ স্পিটজ

0

আমি এই ক্ষেত্রে একই ত্রুটি পেয়েছি:

var result = Db.SystemLog
.Where(log =>
    eventTypeValues.Contains(log.EventType)
    && (
        search.Contains(log.Id.ToString())
        || log.Message.Contains(search)
        || log.PayLoad.Contains(search)
        || log.Timestamp.ToString(CultureInfo.CurrentUICulture).Contains(search)
    )
)
.OrderByDescending(log => log.Id)
.Select(r => r);

ডিবাগ করার জন্য অনেক বেশি সময় ব্যয় করার পরে, আমি বুঝতে পারি যে ত্রুটিটি যুক্তি প্রকাশে প্রকাশ পেয়েছে।

প্রথম লাইনটি search.Contains(log.Id.ToString())সূক্ষ্মভাবে কাজ করে তবে ডেটটাইম অবজেক্টের সাথে সম্পর্কিত শেষ লাইনটি এটি খারাপভাবে ব্যর্থ করেছিল:

|| log.Timestamp.ToString(CultureInfo.CurrentUICulture).Contains(search)

সমস্যাযুক্ত লাইন এবং সমস্যা সমাধান করা সরান।

আমি কেন পুরোপুরি বুঝতে পারছি না তবে এটি মনে হচ্ছে টোস্ট্রিং () স্ট্রিংগুলির জন্য একটি লিনকিউ এক্সপ্রেশন, তবে সত্তার পক্ষে নয়। সংস্থাগুলির জন্য লিনিক্যু এসকিউএল এর মতো ডাটাবেস প্রশ্নগুলির সাথে ডিল করে এবং এসকিউএল তে টসস্ট্রিং () এর কোনও ধারণা নেই। যেমন, আমরা ToString () কে একটি .Where () ধারাতে ফেলতে পারি না।

তবে কিভাবে প্রথম লাইন কাজ করে? টসস্ট্রিং () এর পরিবর্তে এসকিউএল রয়েছে CASTএবং CONVERTতাই এখন পর্যন্ত আমার সর্বোত্তম অনুমান হ'ল সত্তার জন্য লিনক কিছু সাধারণ ক্ষেত্রে এটি ব্যবহার করে। ডেটটাইম অবজেক্টগুলি সর্বদা এত সহজ বলে পাওয়া যায় না ...


-8

আপনার লিনকিউ ক্যোয়ারিতে যে কোনও সময় আপনাকে কোনও মেথড কল ব্যবহার করার প্রয়োজন হলে কেবল লিনকিউকে সত্তা ক্যোয়ারিকে অবজেক্ট ক্যোয়ারিতে (যেমন টোআররে কল করুন) একটি লিনকুইতে রূপান্তর করুন।


3
"যে কোনও সময় আপনাকে কোনও মেথড কল ব্যবহার করা দরকার" হ'ল দুর্বল পরামর্শ - অনেক রেকর্ডের সাথে এটি একটি বড় সমস্যা হতে পারে। এই দৃশ্যের জন্য গৃহীত উত্তরটি আরও ভাল।
পেটগো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.