我的车型:
public class Vehicle : EntityObject
{
private Lazy<string> _nameFromDelegate = null;
private Lazy<IList<Component>> _components = null;
public Vehicle(int id, string name, Lazy<string> nameFromDelegate, Lazy<IList<Component>> components)
: base(id)
{
this.Name = name;
this._nameFromDelegate = nameFromDelegate;
}
public string Name { get; private set; }
public string NameFromDelegate
{
get
{
return this._nameFromDelegate.Value;
}
}
public IList<Component> Components
{
get
{
return this._components.Value;
}
}
}
我想使用构造函数在L2S中投影我的类型,并将某些映射作为委托传递,因此它们在内存中进行评估,而不是L2S尝试将它们转换为SQL.
在下面的示例中,我尝试将SQL中的“vehicle.Name”值映射到我的Vehicle类型上的两个属性:“Name”字符串属性和“NameFromDelegate”字符串属性(封装Lazy< string>).
我希望证明它对L2S没有任何影响,无论我将“vehicle.Name”传递给字符串ctor param还是传递给Lazy< string> ctor param.但也许它确实如此:
我不明白为什么需要从字符串转换为Func< string>.想法?
堆栈跟踪供参考:
at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
at System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at System.Data.Linq.DBConvert.ChangeType(Object value, Type type)
at Read_Vehicle(ObjectMaterializer`1 )
at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReader`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at DelegateQueries.Models.VehicleRepoWithDelegates.GetAll() in %path%\DelegateQueries\Models\VehicleRepoWithDelegates.cs:line 26
at DelegateQueries.Tests.RepoTests.VehicleRepo_CanReturn_NameFromDelegateProp_InLinq_WithDelegate() in %path%\DelegateQueries\DelegateQueries.Tests\RepoTests.cs:line 31
最佳答案 这似乎解决了这个问题:
static Lazy<T> Lazyfy<T>(T input)
{
return new Lazy<T>(() => input);
}
public IQueryable<Vehicle> Vehicles()
{
return from veh in ctx.vehicles
select new Vehicle(veh.id, veh.name, Lazyfy(veh.name), null);
}
更新你也可以这样做:
static Func<T> Functify<T>(T input)
{
return () => input;
}
public IQueryable<Vehicle> Vehicles()
{
return from veh in ctx.vehicles
select new Vehicle(veh.id, veh.name, new Lazy<string>(Functify(veh.name)), null);
}
但你不能这样做:
var r = from veh in ctx.vehicles
select new Func<int>(() => veh.id);
r.ToList();
似乎L2S将lambda表达式创建视为值赋值,而不是作为方法调用,并尝试将db中的值转换为它.我说这是一个bug,因为这适用于linq对象.