linq-to-sql – 如何将Lazy传递给我的投影?

我的车型:

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对象.

点赞