首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将IQueryable<EntityObject>转换为IQueryable<Specific>

将IQueryable<EntityObject>转换为IQueryable<Specific>
EN

Stack Overflow用户
提问于 2012-01-11 20:07:01
回答 5查看 11.8K关注 0票数 11

我们正在尝试将IQueryable<EntityObject>的实例强制转换为IQueryable<SpecificEntityObject>SpecificEntityObject类型仅在运行时才知道。

我们已尝试使用下面的代码,但该代码无法编译,因为类型或命名空间“objType”不存在。

代码语言:javascript
复制
var t = query.ElementType;
Type objType = typeof(IQueryable<>).MakeGenericType(t);
var typed = query.Cast<IEnumerable<objType>>();


var grouped = typed.GroupByMany(groupBy.Select(grp => grp.Expression).ToArray());

有什么想法吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-01-11 20:22:54

使用以下IQueryable扩展泛型方法query.ToDTO<sourceType,DestType>();

代码语言:javascript
复制
public static class QueryableExtensions
{
    public static IQueryable<TDest> ToDTO<TSource, TDest>(this IQueryable<TSource> source)
    {
        List<TDest> destinationList = new List<TDest>();
        List<TSource> sourceList = source.ToList<TSource>();

        var sourceType = typeof(TSource);
        var destType = typeof(TDest);
        foreach (TSource sourceElement in sourceList)
        {
            TDest destElement = Activator.CreateInstance<TDest>();
            //Get all properties from the object 
            PropertyInfo[] sourceProperties = typeof(TSource).GetProperties();
            foreach (PropertyInfo sourceProperty in sourceProperties)
            {
                //and assign value to each propery according to property name.
                PropertyInfo destProperty = destType.GetProperty(sourceProperty.Name);
                destProperty.SetValue(destElement, sourceProperty.GetValue(sourceElement, null), null);
            }
            destinationList.Add(destElement);
        }

        return destinationList.AsQueryable();
    }
}
票数 9
EN

Stack Overflow用户

发布于 2015-12-08 14:51:47

对于任何想要从数据库查询中投影非数据库值的人来说,来自u/Luis Aguilarthis项目对我非常非常有帮助。

我有一个非常大的遗留数据库(450 be ),需要将其提供给OData/WebAPI。

OData要求意味着在将源数据返回给用户之前,我不能过滤源数据(很多)。我们可以孤立它,但除此之外,它是他们的数据查询他们想要的。

然而,更重要的是,遗留数据过于复杂,无法按原样公开,而且需要大量的业务逻辑来整理必要的数据(导航属性/外键的Include、冗长的子句谓词等)。

这意味着分页和结果限制直到查询被物化之后才可用。

这类事情的正常捷径包括各种策略,这些策略涉及物化/急切加载。然而,由于数据集的大小和缺乏过滤,这将导致大量进程内存膨胀和内存不足崩溃。

所以,一些代码。下面是我的配置调用,类似于AutoMapper或OData所需的:

代码语言:javascript
复制
using ExpressionFramework.Projections;
using ExpressionFramework.Projections.Configuration;

public class ProjectionModelBuilder : ProjectionModel
{
    protected override void OnModelCreating(ProjectionModelBuilder modelBuilder)
    {
        ClientDTO.ProjectionModel(modelBuilder);
        OrderDTO.ProjectionModel(modelBuilder);
        AnotherDTO.ProjectionModel(modelBuilder);
    }
}

这种设计允许我将投影规则与其余业务逻辑一起保留在DTO类中。下面是DTO级别的代码:

代码语言:javascript
复制
public static void ProjectionModel(ProjectionModelBuilder modelBuilder)
{
    modelBuilder
        .Projection<ClientDTO>()
        .ForSource<Client>(configuration =>
        {
            configuration.Property(dto => dto.Name).ExtractFrom(entity => entity.Name);
            // etc
        });
}

其中Client是我的实体/EDM类型,映射到db表和无数个外键。

然后,要获得转换/投影的Queryable,就是这样:

代码语言:javascript
复制
IClientQueryService service = _ioc.Resolve<IClientQueryService>(); // Repository pattern 
var q = service.GetClients(); // withManyNavigationIncludes
var r = q.Where<Item>(
    i =>
        i.Name != null
        && i.Name != ""
        // lather rinse repeat, with many sub-objects navigated also
    ).AsQueryable();
var projectionModel = new ProjectionModelBuilder();
var s = projectionModel.Project<ClientDTO, Client>(r).AsQueryable();

只有最后两行是相关的,但为了上下文而包含了其余行。

我要做的最后一件事是在Luis的代码中为ProjectionSourceTypeConfiguration.cs的构造函数设置this.IsAutoConfigured = false;;这允许我手动对投影定义进行排序,这样父类中的导航属性就可以成功地配置它们的投影。

我对https://stackoverflow.com/users/543712/luis-aguilar的工作感激不尽。在编写了我自己的LINQ Provider/ExpressionVisitor并使用各种泛型方法调用、转换和树遍历仍然存在各种问题之后,他的项目简直是天赐之物。

如果您确实发现出于性能或其他原因而不得不使用管道进行自己的表达式处理,我建议从these two answers开始。

票数 1
EN

Stack Overflow用户

发布于 2012-01-11 20:17:45

如果你开始使用反射,你也需要在所有的方法中使用它。所以你需要创建

代码语言:javascript
复制
var myEnumType = typeof(IEnumerable<>).MakeGenericType(objType);

还可以在运行时找到与所需类型匹配的扩展方法强制转换。

代码语言:javascript
复制
 myEnumType.GetMethod("Cast", BindingFlags.Public |
                BindingFlags.Static, 
                null, 
                CallingConventions.Any,  
                new Type[] {typeof(object)}, 
                null);

然后您就可以调用该方法了

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8818938

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档