例如,我们有ProcessAndSortXXXXX类方法.
private static IEnumerable<ClassErrorEntry> ProcessAndSortClassErrorLog(IQueryable<ClassErrorDb> queryable,string sortOrder) { var dynamic = queryable; if (!String.IsNullOrEmpty(sortOrder.Trim())) { dynamic = dynamic.OrderBy(sortOrder); } return dynamic .Select(l => new ClassErrorEntry(l.Id) { ClassId = l.ClassId,Code = l.Code,Message = l.Message,Severity = l.Severity,Target = l.Target } ); }
…和…
private static IEnumerable<ClasstimerLogEntry> ProcessAndSortClasstimerLog(IQueryable<ClasstimerDb> queryable,string sortOrder) { var dynamic = queryable; if (!String.IsNullOrEmpty(sortOrder.Trim())) { dynamic = dynamic.OrderBy(sortOrder); } return dynamic .Select(l => new ClasstimerLogEntry(l.Id) { ClassName = l.ClassName,MethodName = l.MethodName,StartTime = l.StartTime,EndTime = l.EndTime,ParentId = l.ParentId,Executionorder = l.Executionorder } ); }
正如您可以从代码中看出的那样,它们都非常相似,直到您查看签名然后转到返回语句,我们正在构建ClassErrorEntry和ClasstimerLogEntry的实例.
我想构建一个实用程序方法,我将其添加到所有存储库继承的基类中.
我希望能够传入可用于实例化对象的参数,并将它们打包到返回的IEnumerable中.
我在ScottGu年找到了this post,这让我得到了我需要的大部分内容.它看起来像这样(来自文档中的示例):
var query = db.Customers. Where("City = @0 and Orders.Count >= @1","London",10). OrderBy("CompanyName"). Select("new(CompanyName as Name,Phone)");
不过,这是我被困的地方.我需要一个指针或建议如何以通用方式传递LINQ表和DataContext,以便我可以构建动态查询.
如果我用伪代码模拟签名,我认为它看起来像这样:
protected internal IEnumerable ProcessAndSort(IQueryable source,string selectClause,string whereClause,string orderByClause);
我意识到完成的签名可能看起来不同,因为我们想出来了.
谢谢!
更新!
public static IEnumerable<TResult> ProcessAndSort<T,TResult>(IQueryable<T> queryable,string selector,Expression<Func<T,bool>> predicate,string sortOrder) { var dynamic = queryable.Where(predicate).AsQueryable(); if (!String.IsNullOrEmpty(sortOrder.Trim())) { dynamic = dynamic.OrderBy(sortOrder); } var result= dynamic.Select(selector).Cast<TResult>(); return result; }
[TestMethod] public void TestAnonymousClass() { var loggingContext = new LoggingDbDataContext(DatabaseConnectionString); var repo = new LoggingRepository(loggingContext); var result = repo.TestGetClassErrorLog(4407,10,"new ( ClassId as ClassId," + "Code as Code," + "Message as Message," + "Severity as Severity," + "Target as Target )","Target"); TestContext.WriteLine(result.ToList().Count.ToString()); }
最后一行TestContext.WriteLine(result.ToList().Count.ToString());抛出异常system.invalidOperationException:类型’Dynamicclass1’和’Utilities.Logging.ClassErrorEntry’之间没有定义强制运算符.
这段代码虽然失败了:
[TestMethod] public void TestNamedClass() { var loggingContext = new LoggingDbDataContext(DatabaseConnectionString); var repo = new LoggingRepository(loggingContext); var result = repo.TestGetClassErrorLog(4407,"new ClassErrorEntry(Id) { ClassId = ClassId," + "Code = Code," + "Message = Message," + "Severity = Severity," + "Target = Target }","Target"); TestContext.WriteLine(result.ToList().Count.ToString()); }
这在解析错误时失败.测试方法eModal.Repositories.Test.RepositoryBaseTest.TestConcreteClass抛出异常:
System.Linq.Dynamic.ParseException:'(‘期望,在’新ClassErrorEntry(Id)中的char 19处找到’ClassErrorEntry'(‘Identifier’){ChassisAuthId = ChassisAuthId,Code = Code,Message = Message,Severity = Severity,Target =目标}’
解决方法
代码重用是为了提高可维护性,但如果以错误的方式使用,弱类型可能会导致代码重用.
通过以纯文本形式编写查询,您有效地使类很难重构和更改,并引入了许多模糊的依赖项.
我建议你看看LinqKit,它允许组合表达式.例如,我们编写了一个Paging方法,该方法按页面拆分查询,并在不同类型的项目中使用它:
var query = CompiledQuery.Compile( BuildFolderExpr( folder,false ) .Select( msg => selector.Invoke( msg,userId ) ) // re-use selector expression .OrderBy( mv => mv.DateCreated,SortDirection.Descending ) .Paging() // re-use paging expression .Expand() // LinqKit method that "injects" referenced expressions ) public static Expression<Func<T1,T2,PagingParam,IQueryable<TItem>>> Paging<T1,TItem>( this Expression<Func<T1,IQueryable<TItem>>> expr ) { return ( T1 v1,T2 v2,PagingParam p ) => expr.Invoke( v1,v2 ).Skip( p.From ).Take( p.Count ); }
在我的示例中,BuildMessageExpr返回一个相对简单的select表达式(已经依赖于文件夹和另一个参数),并且不同的方法通过应用过滤,排序,获取计数,进一步选择并将选择器表达式作为参数传递来重用此表达式,等等.创建查询后,当参数相似时,它将被缓存以供将来使用.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。