Bu beni gerçekten şaşırtıyor. LINQ-to-SQL, ifade ağacını işleyerek ve oluşturulan sorgu aracılığıyla bir şeyler çevirmeye çalışarak seçimleri işlediğini biliyorum, bu nedenle bazı işlev çevirileri özelliği çalışmaz (string.IsNullOrWhitespace
düzenli bir sıkıntıdır).Neden LINQ-to-SQL bazen bir işlevi kullanarak proje oluşturmama izin veriyor, ancak bazen yapmıyor?
Kodumda LINQ-to-SQL'in bir Select projeksiyonu ... aracılığıyla yardımcı işlevimi çağırabildiği bir duruma rastladım. Aslında, yöntem bir adı olduğunda çalışır, ancak başka bir adıyla birlikte çalışmıyor. Ben (bu ben bunu yapabilir gibi yaklaşık olarak basit) bu en iyi aşağıdaki program tarafından gösterilmektedir düşünüyorum:
// #define BREAK_THE_CODE
using System;
using Sandbox.Data;
using System.Collections.Generic;
using System.Linq;
namespace Sandbox.Console
{
class Program
{
static void Main(string[] args)
{
using (var dataContext = new SandboxDataContext())
{
List<MyValue> myValueList;
try
{
myValueList = dataContext.Numbers.Select(x => new MyValue
{
#if BREAK_THE_CODE
Type = ToValueType(x.Value),
#else
Type = DoIt(x.Value),
#endif
}).ToList();
}
catch (NotSupportedException)
{
System.Console.WriteLine("Not supported, oh noes!");
System.Console.ReadKey();
return;
}
System.Console.WriteLine(myValueList.Count);
System.Console.ReadKey();
}
}
#if BREAK_THE_CODE
public static MyValueType ToValueType(int value)
#else
public static MyValueType DoIt(int value)
#endif
{
return MyValueType.One;
}
public sealed class MyValue
{
public MyValueType Type { get; set; }
}
public enum MyValueType
{
One,
Two,
Unknown,
}
}
}
destek veritabanı sadece tek bir sütun [Value] INT NOT NULL
ile [Number]
adlı tek bir tablo vardır.
program benim için çalışıyor, ama üstündeki #define
uncommenting yöntem görüşmesinin adını geçecektir ve ToList()
yürütürken daha sonra program NotSupportedException
atacağım.
Bir kalıbı belirlemeye çalışmak için birkaç farklı yöntem adını denedim, ancak yapamadım.
Metodu, To
ile başlayan herhangi bir şekilde adlandırılmış gibi görünüyorsa NotSupportedException
'u atıyor, ancak başka bir adla çalışıyor gibi görünüyor. Bu hala tuhaf.
Birisi neler olduğunu açıklayabilir mi?
Burada #define
geçişi olmayan başka bir örnek var, yalnızca her iki yöntemi de arkada yapıyor ve hala aynı sorunu görüyorum. Özellikle, DoIt
çalışır, ancak ToValueType
yapmaz.
using System;
using Sandbox.Data;
using System.Linq;
namespace Sandbox.Console
{
class Program
{
static void Main(string[] args)
{
using (var dataContext = new SandboxDataContext())
{
try
{
var myValueList = dataContext.Numbers.Select(x => new MyValue
{
Type = DoIt(x.Value),
}).ToList();
System.Console.WriteLine("DoIt Succeeded, found {0} results", myValueList.Count);
}
catch (NotSupportedException)
{
System.Console.WriteLine("DoIt Failed, oh noes!");
}
try
{
var myValueList = dataContext.Numbers.Select(x => new MyValue
{
Type = ToValueType(x.Value),
}).ToList();
System.Console.WriteLine("ToValueType Succeeded, found {0} results", myValueList.Count);
}
catch (NotSupportedException)
{
System.Console.WriteLine("ToValueType Failed, oh noes!");
}
System.Console.ReadKey();
}
}
public static MyValueType DoIt(int value)
{
return MyValueType.SpecialType;
}
public static MyValueType ToValueType(int value)
{
return MyValueType.SpecialType;
}
public sealed class MyValue
{
public MyValueType Type { get; set; }
}
public enum MyValueType
{
SpecialType,
}
}
}
ToValue Çalışmayan tek dizeyi mi? Eğer söyledikleriniz doğruysa ve bunu varsaymak için tedbirliyim, bu bir L2S hatasıdır (gerçekten sıra dışı olanı). – usr
Normalde, L2S son Seçimde sadece iyi işlevler çalıştırabilir. Bu, EF'in hala eksik olduğu harika bir özellik. – usr
LINQPad'de bile anlattığınız davranışı yeniden üretebildim, her bir "To" (büyük/küçük harf duyarlı) ile başlayan bir yöntemi kullandığınızda, bir istisna atar. –