匿名类型列表的声明

时间:2014-03-13 22:06:28

标签: c# linq

我不知道问题是否格式正确,但我尝试做的是在var reservations循环之外创建using但不知道如何初始化它。

此代码有效:

using (MainContextDB db = new MainContextDB())
{
    var reservations = (from c in db.Reservations select new { c.CustAcctNo, c.ReservNo, c.ReservStatus }).ToList();
}

任何在循环外声明var的尝试都会触发错误:

  

无法将列表转换为列表

我试过了:

var reservations = new List<dynamic>();
var reservations = new List<object>();

此代码有效,但需要检索所有列,这不是我想要的:

List<Reservation> reservations = new List<Reservation>();
using (MainContextDB db = new MainContextDB())
{
    reservations = db.Reservations.ToList();
}

3 个答案:

答案 0 :(得分:2)

你可以这样做:

var reservations = new []
{
    new { CustAcctNo = "", ReservNo = "", ReservStatus = "" }
}.ToList();

using (MainContextDB db = new MainContextDB())
{
    reservations = (
        from c in db.Reservations
        select new
        {
            c.CustAcctNo, c.ReservNo, c.ReservStatus
        }).ToList();
}

您必须确保匹配匿名类成员的类型。


另一个选项是添加对Microsoft Reactive Framework Team&#34; Interactive Extensions&#34;的引用。他们有一个很好的Using enmerables方法,可以让你这样做:

var reservations = 
    EnumerableEx
        .Using(
            () => new MainContextDB(),
            db =>
                from c in db.Reservations
                select new
                {
                    c.CustAcctNo, c.ReservNo, c.ReservStatus
                })
        .ToList();

答案 1 :(得分:1)

好的,这最终成为一个非常有趣的问题 -

我知道匿名类型不应该离开方法上下文,但是他们并没有真正想过它们会留下范围......

我看到了一些可能的选择......

  • 做一些hackey - 具有相同签名的两个anon类型共享相同类型,因此您可以强制它接受原型并从那里开始。 (转换成列表很困难,但在泛型中可行...请参阅simo发布的链接)

  • 将操作移至您认为不理想的使用环境

  • 手动处理上下文

  • 将项目处理为动态

  • 您可以将自定义类型或元组替换为匿名类型

希望有所帮助,我有点惊讶,如果你留在方法范围内,没有一种直接的方法可以做到这一点。

答案 2 :(得分:0)

注意:我不会在性能敏感的代码中使用以下方法。

话虽如此,我在这里看到一个非常简单的解决方案,当你处理List<T>以外的类型时,也可以应用这个解决方案。一些类型的推断可以完成工作:

private T InvokeAndReturn<T>(Func<T> func)
{
    return func();
}

用法:

// reservations is List<'a>.
var reservations = this.InvokeAndReturn(() =>
{
    using (var db = new MainContextDB())
    {
        return db.Reservations
            .Select(c => new { c.CustAcctNo, c.ReservNo, c.ReservStatus })
            .ToList();
    }
});

新编辑

只需在我自己的代码中使用它,然后选择IDisposable - 知道替代方案:

TReturn Using<TDisposable, TReturn>(TDisposable disposable, Func<TDisposable, TReturn> func)
    where TDisposable : IDisposable
{
    try
    {
        return func(disposable);
    }
    finally
    {
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }
}

用法:

var reservations = Using(new MainContextDB(), db =>
{
    return db.Reservations
        .Select(c => new { c.CustAcctNo, c.ReservNo, c.ReservStatus })
        .ToList();
});

或更短的版本

var reservations = Using(new MainContextDB(), db =>
    db.Reservations
        .Select(c => new { c.CustAcctNo, c.ReservNo, c.ReservStatus })
        .ToList()
);