如何将Lazy <t>传递给我的投影?</t>

时间:2011-03-29 09:00:18

标签: linq-to-sql domain-driven-design projection lazy-evaluation

我的Vehicle类型:

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”string属性和“NameFromDelegate”{ {1}}属性(封装string)。

我希望证明,无论我将“vehicle.Name”传递给Lazy<string> ctor param还是传递给string ctor param,它对L2S没有任何影响。但也许它确实如此: enter image description here

我不明白为什么需要从Lazy<string>投射到string。想法?

堆栈跟踪以供参考:

Func<string>

1 个答案:

答案 0 :(得分:2)

这似乎解决了这个问题:

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