【问题标题】:Linq how to Extend\Override existing toList() MethodLinq 如何扩展\覆盖现有的 toList() 方法
【发布时间】:2016-06-17 22:01:48
【问题描述】:

我正在使用 Linq to Sql。我想在调用 (System.Linq) toList() 方法时打开事务范围。因此,我试图通过创建自定义扩展类来覆盖默认的 toList() 方法,从而创建新版本的 toList()。但是在自定义 toList() 扩展中,我想调用现有的默认 (system.linq) ToList() 方法。但我无法做到这一点。请看下面的例子:

代码:

public static int GetRecordsWithNoChangeToQuery()
{
    string connection = ConfigurationManager.ConnectionStrings["EventConn"].ConnectionString;
    using (var ctx = new EventsDataContext(connection))
    {
        var records = (from m in ctx.Event select m).ToList(); //calling custom extension method
        return records.Count();
    }
}

LinqExtenionHeler

public static class LinqExtension
{
    public static TransactionScope CreateLockTransaction()
    {
        var options = new TransactionOptions
        {
            IsolationLevel = IsolationLevel.ReadCommitted
        };
        return new TransactionScope(TransactionScopeOption.Required, options);
    }

    //custom extension method
    public static List<T> ToList<T>(this IEnumerable<T> query)
    {
        using (TransactionScope ts = CreateLockTransaction())
        {
            return query.ToList(); //fails, not able to call system.linq .toList method
        }
    }
}

在上面的代码中,当我调用 query.ToList() 时,它会抛出错误。因为,它正在尝试调用自己。那么如何从同名自定义扩展方法调用默认(syste.linq)query.toList()?

【问题讨论】:

  • 虽然你可以这样做,但你不应该这样做。你应该给这个方法一个不同的名字,否则它会导致方式比它增加的价值更多的混乱。
  • System.Linq.Enumerable.ToList(query)(但Servy所说)
  • 谢谢丹尼斯。它有效
  • 你知道如何以上述方式调用 .SingleorDefault() 吗?

标签: c# linq linq-to-sql


【解决方案1】:

扩展方法只是调用公共静态方法的一种奇特方式。您仍然可以按正常方式调用它,有时您必须这样做。

 return System.Linq.Enumerable.ToList(query); 

但是,我确实支持那些尖叫“等等,你为什么要这样做?”的 cmets。这似乎是解决此问题的次优方法。也许您应该就您的问题提出一个更开放的问题,以便为您的全局问题获得更好的答案,这只是解决您的本地句法问题。

【讨论】:

  • 其实我想为遗留类添加事务支持。所以我不想更改每个“linq to sql”查询,这就是为什么我要创建一个新版本的 toList()。如果您知道无需大量代码更改的更好解决方案,请告诉我?
【解决方案2】:

您为 List 创建的扩展方法,它将在内部调用自身,因为查询类型为 IEnumerable,这将通过异常或可能处于死锁状态。 因此对于 ToList 扩展方法,您可以做一件事,即传递参数可以是 IQueryable。 所以语法是-

public static List<T> ToList<T>(this IQueryable<T> query)
{ using (TransactionScope ts = CreateNoLockTransaction()) { return query.AsEnumerable().ToList(); } }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多