动态地更改表达式中参数的类型而无需在代码时知道目标类型

时间:2018-12-10 10:20:27

标签: c# entity-framework linq expression

可以说我有一个Animal类,其中有一些后代,例如Dog CatMouse

public class Animal{}
public class Dog : Animal {}
public class Cat : Animal {}
public class Mouse: Animal {}

现在,可以说这些对象的实体存储在sql数据库中,并且我使用Entity Framework与该数据库进行通信。狗,猫和老鼠都存储在不同的表中,但是在代码中它们共享相同的父代。

如果我想获得所有满足相同表达式的动物,则必须分别查询每个DbSet并为其赋予相同的表达式,但参数类型不同,因此,猫得到的是猫参数类型,狗得到的是狗像这样的参数

var cats = context.Cats.Where(p=>some expression);
var dogs= context.Dogs.Where(p=>some expression);
var mice= context.Mice.Where(p=>some expression);
var animals = new List<Animal>();
animals.AddRange(cats);
animals.AddRange(dogs);
animals.AddRange(mice);

但是,这给我带来了一个问题,因为如果我想添加另一种动物类型,例如Bird,我将不得不添加另一行代码来从数据库中获取数据并将其添加到结果中采集。此行为很难处理,我希望它能遍历从Animal派生的类型,并根据提供的源表达式以编程方式构造一个适当类型的表达式,该源表达式作为参数传递给方法{{1} }类型表达式。像这样:

Animal

有没有办法做到这一点?我曾考虑过更改表达式参数类型,但是我似乎无法在代码时不知道正确的参数类型的情况下弄清楚它。

3 个答案:

答案 0 :(得分:1)

我认为您应该再次查看数据设计。在这里,您可以解决很多问题。

您可以使用SQL SERVER VIEW从相关表中使用UNION返回不同表中的动物。添加新的动物表需要在视图中添加新的UNION。

您还可以使用存储过程执行相同的操作。为了确保更新正确的表格,我会使用一种来获取动物,并使用一种来保存动物。

您可以将所有动物存储在一个表中,并具有一个AnimalType字段,该字段链接到另一个具有ID和AnimalTypeName的简单表。这样,添加新动物就很简单。

还有实体表继承与要考虑的表 https://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt

答案 1 :(得分:0)

A可以建议您一个更简单的解决方案。由于在代码中您确实将Animal作为父项,因此您可以对数据库执行相同的操作。

更确切地说,不是具有用于猫,狗等的不同表,而是具有一个表Animal(因为属性应该相同),其属性类似于枚举“ AnimalType”。

从这里开始查询将非常简单。

这不是最好的解决方案,但它是可行的。

答案 2 :(得分:0)

我喜欢利用数据库应用程序的功能,而不是假设C#代码(用于检索数据)更有效。我也将其视为关注点分离。在这种情况下,需要一些技巧来设置数据库表(键,其他索引等)以及视图,存储过程等。

继承数据库中的对象并不常见。您可以采取几种方法。哪个最好,不仅取决于涉及多少行和列以及您要对数据执行什么操作。以您的动物等级为例: 在继承中,通常将上推归纳和下推归纳,因此,我们从创建“ Animals”表开始。它有一个整数字段“ Id”,它是密钥。我们还有一个字段“动物名”。

现在让我们创建一个“猫”表。和“ Id”字段被使用,但是我们有一个外键“ AnimalId”链接到动物表“ Id”。我们添加了其他猫常见的字段。就像您刚开始时一样,我们对鼠标和其他动物也是如此。

实现上述目标的另一种方法是对所有动物使用一张桌子。现在,您需要更多的列来获取更多的动物类型。这具有较高的维护方法,这种方法可能经常发生更改,但是在使用较小的固定范围的对象时效果很好。无论类型如何,检索常见数据的一种简单方法是使用计算列,该计算列从每种对象类型的相关字段中输出一个varchar。

另一种方法是拥有具有所有常见属性的单个动物表。第二个表存储“属性名称/值”对。现在,每种动物都可以具有许多不同的属性,并且很容易从前端代码进行维护。该数据结构具有简单,固定的设计,但到目前为止仍支持您所需要的所有内容。但是,此设计对您有多有用,取决于需要对数据进行多少分析。在数据库中,您必须将基于行的数据平整为列以进行某些分析处理。