Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在EF中使用基类创建IQueryable<T>扩展

在EF中使用基类创建IQueryable<T>扩展
EN

Stack Overflow用户
提问于 2018-12-10 21:08:14
回答 2查看 701关注 0票数 0

我试图在我的基类上创建可重用的搜索查询,这样我就不必为每个派生的类重复相同的代码,但我无法让实体框架很好地发挥作用。

我有3个类: CMEntityBase CMSite CMSiteServer

Site & SiteServer都是从具有共同属性(ID、名称等)的CMEntityBase派生而来的

我想定义一些通用搜索:例如GetByName

代码语言:javascript
运行
AI代码解释
复制
using (var db = new LNOSCMDataModel())
            {
                db.Configuration.LazyLoadingEnabled = false;
                var servers = db.CMSiteServers.
                    AsNoTracking().
                    GetByName(id,Active).
                    ConvertToAPIVM().ToList();
}

我尝试过几种定义GetByName的方法:

基类:

代码语言:javascript
运行
AI代码解释
复制
    public static IQueryable<CMEntityBase> GetByName(this IQueryable<CMEntityBase> Entities, string Name, bool Active = true)
    {
        return Entities.Where(ss => ss.Name == Name && ss.Active == Active || Active == false);//.Cast<IEntity>();
    }

泛型:

代码语言:javascript
运行
AI代码解释
复制
public static IQueryable<T> GetByName<T>(this IQueryable<CMEntityBase> Entities, string Name, bool Active = true) where T : CMEntityBase
        {
            return Entities.Where(ss => ss.Name == Name && ss.Active == Active || Active == false).Cast<T>();
        }

我尝试过将基类定义为接口,在泛型中使用T: class,IEntity (接口) -->这种方法来自:LINQ to Entities only supports casting EDM primitive or enumeration types with IEntity interface

最终,它们都会返回错误:

LINQ to Entities仅支持使用IEntity接口强制转换EDM基元或枚举类型。

最终,我希望在基类属性上定义一个查询,但输出子类。现在,我似乎需要复制/粘贴每个派生类的方法。

EN

回答 2

Stack Overflow用户

发布于 2018-12-10 21:18:04

您只需要接受查询已经具有的实际类型的IQueryable,而不是接受与您想要的类型不同的IQueryable,并尝试强制转换它(如错误所示,不受支持),这样就不需要强制转换它。在这种情况下,就像在原始查询中使用泛型类型一样简单,而不是使用基类型:

代码语言:javascript
运行
AI代码解释
复制
public static IQueryable<T> GetByName<T>(this IQueryable<T> Entities, string Name, bool Active = true)
    where T : CMEntityBase //or the interface that specifies the needed members
{
    return Entities.Where(ss => ss.Name == Name && ss.Active == Active || Active == false);
}
票数 0
EN

Stack Overflow用户

发布于 2018-12-10 21:08:14

经过大量实验之后,解决方案是将基类创建为抽象类

代码语言:javascript
运行
AI代码解释
复制
public abstract class CMEntityBase
{

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public abstract decimal ID { get; set; }


    [StringLength(50)]
    public abstract string Name { get; set; }

    ....
}

在静态扩展类中定义我的扩展,这里的关键是使用.Select( e=> e T)将其转换回子类

代码语言:javascript
运行
AI代码解释
复制
public static partial class CMEntityBaseExtensions
{
    public static IQueryable<T> GetByName<T>(this IQueryable<T> Entities, string Name, bool Active = true) where T : CMEntityBase
    {
        return Entities.Where(ss => ss.Name == Name && ss.Active == Active || Active == false).
                 Select(e => e as T); // cast back to child!
    }
}

然后我可以在我的控制器中使用它:

代码语言:javascript
运行
AI代码解释
复制
 var servers1 = db.CMSiteServers
                .AsNoTracking().
                GetByName(id, Active);

和事件使用我的“强制转换”函数来转换为视图模型

代码语言:javascript
运行
AI代码解释
复制
            var servers = servers1.
                ConvertToAPIVM().ToList();

它看起来像这样:

代码语言:javascript
运行
AI代码解释
复制
public static partial class CMSiteServerExtensions
{
    public static IQueryable<CMSiteServerAPIVM> ConvertToAPIVM(this IQueryable<CMSiteServer> Servers)
    {
        return Servers.Select(ss => new CMSiteServerAPIVM()
        {
            SiteServerID = ss.ID,
            Name = ss.Name,
            Description = ss.Description,
            ...
        }
    }
 }
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53713668

复制
相关文章
TestNG忽略测试和预期异常
一.有时候我们写的代码还没有构思完整, 但测试case又需要执行,testng提供了@Test (Enable=false) ,可以有助于禁用.
louiezhou001
2020/02/25
8860
策略模式:处理不同策略具有不同参数的情况
策略模式确实在处理不同策略需要不同参数的情况下会显得有些复杂。然而,这并不意味着策略模式不能在这种情况下使用。有几种可能的解决方案:
运维开发王义杰
2023/08/16
7060
策略模式:处理不同策略具有不同参数的情况
Junit 4 Tutorials(Junit 4 教程) 四、Junit4 参数化测试
Junit 4 参数化测试 允许通过变化范围的参数值来测试方法。参数擦测试可以通过以下简单的步骤实现:
亦山
2021/09/14
6010
JUnit5参数化测试的几种方式
参数化测试一直是津津乐道的话题,我们都知道JMeter有四种参数化方式:用户自定义变量、用户参数、CSV文件、函数助手,那么JUnit5有哪些参数化测试的方式呢?
dongfanger
2021/07/20
1.2K0
JUnit5参数化测试的几种方式
JUnit4 参数化测试( Parameterized tests)
  当类被@RunWith注解修饰,或者类继承了一个被该注解修饰的类,JUnit将会使用这个注解所指明的运行器(runner)来运行测试,而不使用JUnit默认的运行器。
明明如月学长
2021/08/27
3.2K0
Spring Boot Junit4 参数化测试Controller
由于Spring测试类上只能有一个@Runwith注解,如果使用@RunWith(Parameterized.class),就无法s使用@RunWith(SpringJUnit4ClassRunner.class)。
明明如月学长
2021/08/27
9590
Junit 实例精讲基础教程(五) JUnit套件测试,一次性运行多个测试用例(测试类的测试方法)
前面我们已经了解了使用Junit进行单个方法的测试、以及如何模拟超时测试和异常测试,抛出一个问题:我不想一个一个地去跑测试用例,应该怎么办呢?Junit套件测试为我们提供了解决方案,它可以使用@RunWith(Suite.class)注解结合@Suite.SuiteClasses({Class1.class, Class2.class,… })注解来一次性执行Class1、Class2,…多个测试用例的测试方法。
青山师
2023/05/04
1.6K0
Junit 实例精讲基础教程(五) JUnit套件测试,一次性运行多个测试用例(测试类的测试方法)
Junit5参数化实战,让测试更优雅
在代码的世界里,有一片自动化的花园,那里的用例是微风吹拂下的花朵,绽放着不同的颜色。在这片花园中,我们常常遇到一个美妙的情景:相同的测试流程,却需要随着业务的风向,切换不同的测试数据。这就像是一支曲子,相同的旋律,却因音符的不同而显得迥然不同。
测试蔡坨坨
2023/09/11
5811
Junit5参数化实战,让测试更优雅
软件测试|Junit5 实现参数化和数据驱动
登录:不同的用户名,不同的密码,不同的组合都需要做登录场景的测试,正常的排列组合下可能会产生多个用例
霍格沃兹测试开发Muller老师
2023/01/09
1.3K0
Junit测试 - mockMVC
使用mock工具可以直接模拟http请求,不用直接产生网络的请求环境,简化了测试流程。
Tim在路上
2020/08/04
1.4K0
如何用Junit5玩出参数化测试的新花样?
这是之前一篇文章《用junit5编写一个类ZeroCode的测试框架》的续集。主要将在之前工作的基础上,围绕参数化测试展开。 框架主要设计点:
Criss@陈磊
2019/12/05
1.5K0
如何用Junit5玩出参数化测试的新花样?
如何用Junit5玩出参数化测试的新花样?
这是之前一篇文章《用junit5编写一个类ZeroCode的测试框架》的续集。主要将在之前工作的基础上,围绕参数化测试展开。 框架主要设计点:
Antony
2020/12/01
9480
如何用Junit5玩出参数化测试的新花样?
JUnit5参数化测试扩展3案例
在参数化测试方面,JUnit5提供了较为丰富的数据源,如@ValueSource,支持提供int、float等基本类型以及String和Class等作为参数,@CsvSource可以提供CSV格式的数据。另外还可以通过@MethodSource来提供任意类型的数据。
Antony
2021/06/28
9580
同时使用Junit4的@Parameterized参数化测试和Spring容器
同时使用Junit4的@Parameterized参数化测试和Spring容器整合 ---- 之剑 2016.4.30 整合Spring容器 @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public class TestBase { @Autowired protected TedaCaseService tedaCaseService; private TestCon
一个会写诗的程序员
2018/08/20
6700
SpringBoot异常处理五种方式、Junit单元测试、热部署
首先说明一下,这里使用的是Springboot2.2.6.RELEASE版本,由于Springboot迭代很快,所以要注意版本问题。
别先生
2020/05/26
8450
Junit单元测试
JUnit 是一个 Java 编程语言的单元测试框架。JUnit 在测试驱动的开发方面有很重要的发展,是起源于 JUnit 的一个统称为 xUnit 的单元测试框架之一。
共饮一杯无
2022/11/28
8930
Junit 4 Tutorials(Junit 4 教程) Junit4 七、超时测试
Junit 4超时测试(Timeout test)可以被用来测试方法的执行时间。 Junit 4 超时测试可以被用在:
亦山
2021/09/14
9250
Myexclipse创建Junit测试
. 下载JUnit的jar文件,下载地址在这里 2. 在MyEclipse中新建一个要测试的项目HelloJUnit 3. 添加一个要测试的类HelloJUnit,代码如下,注意需要先建package Java代码   package com.yukaizhao;   public class HelloJUnit {   public String getMessage(){   return "Hello Junit";       }   }   4. 新建一个单元测试项
xiangzhihong
2018/02/01
7860
Myexclipse创建Junit测试
Junit测试类使用
ha_lydms
2023/08/10
1740
【软件测试】JUnit详解
JUnit是一个用于编写和运行Java程序单元测试的开源框架。 它提供了一组注解和断言方法,以及用于执行测试的测试运行器。通过使用JUnit,开发人员可以轻松地编写自动化测试用例,验证代码的正确性,并且能够快速地发现和修复bug。JUnit的使用可以提高代码的质量和可维护性,同时也有助于进行持续集成和持续测试。它被广泛应用在Java开发领域中,成为了标准的单元测试框架之一。
xxxflower
2023/10/16
5710
【软件测试】JUnit详解

相似问题

具有多个测试的参数化junit测试

30

JUnit测试-分析预期的异常

112

组织预期异常的junit测试

24

JUnit中的多个预期异常

26

Junit测试:测试多个异常

44
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档