"একটি বিবৃতি বডি সহ একটি ল্যাম্বডা এক্সপ্রেশন একটি এক্সপ্রেশন ট্রিতে রূপান্তর করা যায় না"


181

সত্তা ফ্রেমওয়ার্কটি ব্যবহার করার সময় , A lambda expression with a statement body cannot be converted to an expression treeনিম্নলিখিত কোডটি সংকলনের চেষ্টা করার সময় আমি ত্রুটি পেয়েছি :

Obj[] myArray = objects.Select(o =>
{
    var someLocalVar = o.someVar;

    return new Obj() { 
    Var1 = someLocalVar,
    Var2 = o.var2 };
}).ToArray();

আমি জানি না ত্রুটির অর্থ কী এবং এর বেশিরভাগ ক্ষেত্রে কীভাবে এটি ঠিক করা যায়। কোন সাহায্য?


6
এই মত তালিকায় রূপান্তর করার চেষ্টা করুন। অবজেক্ট.লিস্ট ()। নির্বাচন করুন (...
নেলসন

উত্তর:


114

কি objectsএকটি Linq টু SQL ডাটাবেস প্রসঙ্গ? কোন ক্ষেত্রে, আপনি কেবল => অপারেটরের ডানদিকে সাধারণ এক্সপ্রেশন ব্যবহার করতে পারেন। কারণটি হ'ল, এই এক্সপ্রেশনগুলি কার্যকর করা হয় না, তবে ডাটাবেসের বিরুদ্ধে কার্যকর করতে এসকিউএল রূপান্তরিত হয়। এটা চেষ্টা কর

Arr[] myArray = objects.Select(o => new Obj() { 
    Var1 = o.someVar,
    Var2 = o.var2 
}).ToArray();

102

আপনি মূল সংখ্যা সংগ্রহের জন্য লাম্বা অভিব্যক্তিতে স্টেটমেন্ট বডি ব্যবহার করতে পারেন । আর একবার চেষ্টা কর:

Obj[] myArray = objects.AsEnumerable().Select(o =>
{
    var someLocalVar = o.someVar;

    return new Obj() 
    { 
        Var1 = someLocalVar,
        Var2 = o.var2 
    };
}).ToArray();

বিজ্ঞপ্তি:
এই পদ্ধতিটি ব্যবহার করার সময় সাবধানতার সাথে চিন্তা করুন, কারণ এইভাবে, আপনার মেমরির সমস্ত প্রশ্নের ফলাফল হবে, যা আপনার কোডের বাকী অংশে অযাচিত পার্শ্ব প্রতিক্রিয়া থাকতে পারে।


4
+1 আমি এটি পছন্দ করি! AsEnumerable()মুখোশ যুক্ত করলে আমার সমস্যা চলে যায়!
জোয়েল

5
এটিই আসল সমাধান, গ্রহণযোগ্য উত্তরটি কিছু ক্ষেত্রে প্রয়োগ করা কঠিন
ফেরান সালগুয়েরো

15
না এটি আসল উত্তর নয়। এটি আপনার প্রশ্নটিকে ক্লায়েন্টের পক্ষ থেকে কার্যকর করাতে সক্ষম করবে। বিশদ জানতে এই প্রশ্নের উল্লেখ করুন: স্ট্যাকওভারফ্লো
লুক ভিও

1
@ ডাটভিএম এটি নির্ভর করে আপনি কী করতে যাচ্ছেন on এটি সর্বদা সঠিক পছন্দ হতে পারে না এবং অবশ্যই সর্বদা ভুল পছন্দ হতে পারে না।
আমির ওভেসি

3
যদিও আমি আপনার সাথে একমত, ওপি জানিয়েছে যে সে এন্টি ফ্রেমওয়ার্ক ব্যবহার করছে। বেশিরভাগ ক্ষেত্রে, ইএফের সাথে কাজ করার সময়, আপনি ডাটাবেস-সাইডটি যতটা সম্ভব কাজ করতে চান। আপনার উত্তরে যদি কেসটি লক্ষ্য করা যায় তবে ভাল লাগবে।
লুক ভিও

39

এর অর্থ হল যে ল্যাম্বডা এক্সপ্রেশনটি যে কোনও এক্সপ্রেশন ট্রিতে রূপান্তরিত হওয়া দরকার যেখানে "স্টেটমেন্ট বডি" (অর্থাৎ লাম্বদা এক্সপ্রেশন যা কোঁকড়া ধনুর্বন্ধনী ব্যবহার করে) দিয়ে ল্যাম্বডা এক্সপ্রেশন ব্যবহার করতে পারবেন না (উদাহরণস্বরূপ লিনক 2 এসকিএল ব্যবহার করার ক্ষেত্রে এটি ক্ষেত্রে) ।


37
আপনি ... ত্রুটিটি সামান্য পুনরায় পোস্ট করেছেন। @ টিম রজার্সের উত্তরটি আরও ভাল ছিল
vbullinger

2
@ ভবুলিংগার আপনি এক ডিগ্রি ঠিকই আছেন তবে আরও সাধারণ অর্থে (লিনক-টু-এসকিএল এর প্রেক্ষাপটের বাইরে) এটি আরও সরাসরি উত্তর answer এটি আমাকে অটোম্যাপার ত্রুটির সাথে সহায়তা করেছে
mlhDev

1
vbullinger: যদিও এটি আমাকে সাহায্য করেছিল।
পল

7

আপনি কী করছেন (লিনক 2 ওবজেক্টস, লিনক 2 এন্টিটিস, লিনক 2 এসকিউএল?) সম্পর্কে আরও না জেনে এটি এটিকে কার্যকর করে তুলবে:

Arr[] myArray = objects.AsEnumerable().Select(o => {
    var someLocalVar = o.someVar;

    return new Obj() { 
        Var1 = someLocalVar,
        Var2 = o.var2 
    }; 
}).ToArray();

11
এটি অনুসন্ধানযোগ্যকে মূল্যায়ন করতে বাধ্য করে।
স্মার্টকাভম্যান

যাইহোক, এই পরিস্থিতিতে এটি ঠিক আছে, কারণ সে যাইহোক, ঠিক পরে ToArray () কল করে।
স্মার্টকাভম্যান

2
অগত্যা নয় - "ও" কত বড় কে জানে? এটির 50 টি সম্পত্তি থাকতে পারে যখন আমরা চাই সমস্ত 2 হয়
কেডাও

1
এই কৌশলটি ব্যবহার করার সময়, আমি কলগুলি করার আগে বেনামে টাইপ করা ক্ষেত্রগুলি নির্বাচন করতে পছন্দ করি.AsEnumerable()
ব্লেক মিচেল

4

নির্বাচনের এই ওভারলোডটি ব্যবহার করুন:

Obj[] myArray = objects.Select(new Func<Obj,Obj>( o =>
{
    var someLocalVar = o.someVar;

    return new Obj() 
    { 
       Var1 = someLocalVar,
       Var2 = o.var2 
    };
})).ToArray();

এটি আমার পক্ষে কাজ করে তবে যখন সত্তা ফ্রেমওয়ার্কের সাথে ব্যবহার করা হয় তখন এই সমাধানটি কী dbcontext কে প্রথমে সমস্ত সারি মেমরিতে লোড করা থেকে আটকাতে পারে যেমন এসইনুমারেবল ()?
সংসদ

2
@ সংসদ: সমস্ত সারি স্মৃতিতে লোড করা রোধ করতে আপনার ব্যবহার করা উচিত Expression<Func<Obj,Obj>>
মোহসেন

4

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

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

Expression<Func<TParam,TResult>>

এক্সপ্রেশন ট্রি শরীরের সাথে ল্যাম্বডা এক্সপ্রেশন সমর্থন করে না এবং এর একমাত্র লাইনের ল্যাম্বডা এক্সপ্রেশনটিকে সমর্থন করে var id = cols.Select( col => col.id );

সুতরাং আপনি চেষ্টা করলে নিম্নলিখিত কোডটি কাজ করবে না।

Expression<Func<int,int>> function = x => {
    return x * 2;
}

নিম্নলিখিতটি প্রত্যাশা অনুযায়ী কাজ করবে।

Expression<Func<int,int>> function = x => x * 2;

2

এর অর্থ হ'ল একটি ল্যাম্বডা এক্সপ্রেশনটি টাইপ করে TDelegateযা একটিতে ([parameters]) => { some code };রূপান্তরিত হতে পারে না Expression<TDelegate>। এটা নিয়ম।

আপনার ক্যোয়ারী সরল করুন। আপনি যে সরবরাহ করেছেন সেটিকে নিম্নলিখিত হিসাবে পুনরায় লেখা যেতে পারে এবং সংকলন করবে:

Arr[] myArray = objects.Select(o => new Obj()
                {
                   Var1 = o.someVar,
                   Var2 = o.var2
                } ).ToArray();

1

কি Arrএকটি বেস টাইপ Obj? ওবজ শ্রেণি কি বিদ্যমান? আপনার কোড কেবল তখনই কাজ করবে যদি অরর ওজ্বের বেস ধরণের হয়। পরিবর্তে আপনি এটি চেষ্টা করতে পারেন:

Obj[] myArray = objects.Select(o =>
{
    var someLocalVar = o.someVar;

    return new Obj() 
    { 
       Var1 = someLocalVar,
       Var2 = o.var2 
    };
}).ToArray();

1

আপনার নির্দিষ্ট ক্ষেত্রে, শরীর একটি পরিবর্তনশীল তৈরি করার জন্য, এবং স্যুইচ করা IEnumerableসমস্ত ক্রিয়াকলাপকে ক্লায়েন্ট-সাইডে প্রক্রিয়াজাত করতে বাধ্য করবে, আমি নিম্নলিখিত সমাধানটি প্রস্তাব করছি।

Obj[] myArray = objects
.Select(o => new
{
    SomeLocalVar = o.someVar, // You can even use any LINQ statement here
    Info = o,
}).Select(o => new Obj()
{
    Var1 = o.SomeLocalVar,
    Var2 = o.Info.var2,
    Var3 = o.SomeLocalVar.SubValue1,
    Var4 = o.SomeLocalVar.SubValue2,
}).ToArray();

সম্পাদনা করুন: সি # কোডিং কনভেনশনের নাম পরিবর্তন করুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.