C# 在LINQ数据库查询中使用接口

C# 在LINQ数据库查询中使用接口,c#,asp.net-mvc,linq,C#,Asp.net Mvc,Linq,我正在开发一个应用程序的一部分,它只是从数据库中提取信息并将其显示给用户。为了简单起见,假设我有一个包含两个表的数据库,Cats和Dogs。这两个表都手动分配了主键,并且从不重复/重叠。我试图实现的目标是执行一个LINQ查询,它将concat两个表 我最近问了一个问题,关于在两个对象集合上执行LINQ concat,这两个对象集合是在code中手动创建的Cats和Dogs。我建议阅读上一个问题,因为它将给这个问题提供更多的见解 我希望使用接口的原因是为了简化查询。我目前有一个解决方案,。选择我需

我正在开发一个应用程序的一部分,它只是从数据库中提取信息并将其显示给用户。为了简单起见,假设我有一个包含两个表的数据库,
Cats
Dogs
。这两个表都手动分配了主键,并且从不重复/重叠。我试图实现的目标是执行一个LINQ查询,它将
concat
两个表

我最近问了一个问题,关于在两个对象集合上执行
LINQ concat
,这两个对象集合是在code中手动创建的
Cats
Dogs
。我建议阅读上一个问题,因为它将给这个问题提供更多的见解

我希望使用接口的原因是为了简化查询。我目前有一个解决方案,
。选择我需要的每个列,将其转换为匿名类型。对于这个实例来说,这可以很好地工作,但会消耗包含我正在处理的数据的页面

上一个问题和这个问题的不同之处在于,我试图从数据库中提取这些动物。根据我的分析,似乎
.NET
实体框架
无法将我的
数据库
与我的
接口

模型(来自旧问题)

下面是我尝试过的一些不同的
LINQ
查询以及由此产生的错误。第一个示例将使用上一个问题的解决方案

var model = _db.Cats.Concat<iAnimal>(_db.Dogs).Take(4);

System.ArgumentException: DbUnionAllExpression requires arguments with compatible collection ResultTypes.

您的数据库对您的接口一无所知,您可能无法使其正常工作。我看到两种选择

您可以使用继承(例如实体框架支持的继承),并从公共基础实体继承这两个实体。然后,您将能够对基类型执行查询,但这可能需要更改数据模型,具体取决于您在数据库级别实现继承的方式

请查看和的文档。还有其他继承模型,如TPC继承,但它们目前缺乏设计器支持

第二个选项是将两个表中的结果提取到内存中,并使用LINQ to对象将它们合并到单个集合中

var dogs = database.Dogs.Take(4).ToList();
var cats = database.Cats.Take(4).ToList();

var pets = dogs.Cast<IPet>().Concat(cats).ToList();
var dogs=database.dogs.Take(4.ToList();
var cats=database.cats.Take(4.ToList();
var pets=dogs.Cast().Concat(cats.ToList();
还要注意,您的查询

var model = _db.Cats.Concat<iAnimal>(_db.Dogs).Take(4);
var模型=_db.Cats.Concat(_db.Dogs).Take(4);

似乎设计得不太好-结果肯定取决于所使用的数据库,但如果您通常只看到前四只猫,而从未见过任何狗,我也不会感到惊讶。

您的数据库对您的界面一无所知,您可能无法使其正常工作。我看到两种选择

您可以使用继承(例如实体框架支持的继承),并从公共基础实体继承这两个实体。然后,您将能够对基类型执行查询,但这可能需要更改数据模型,具体取决于您在数据库级别实现继承的方式

请查看和的文档。还有其他继承模型,如TPC继承,但它们目前缺乏设计器支持

第二个选项是将两个表中的结果提取到内存中,并使用LINQ to对象将它们合并到单个集合中

var dogs = database.Dogs.Take(4).ToList();
var cats = database.Cats.Take(4).ToList();

var pets = dogs.Cast<IPet>().Concat(cats).ToList();
var dogs=database.dogs.Take(4.ToList();
var cats=database.cats.Take(4.ToList();
var pets=dogs.Cast().Concat(cats.ToList();
还要注意,您的查询

var model = _db.Cats.Concat<iAnimal>(_db.Dogs).Take(4);
var模型=_db.Cats.Concat(_db.Dogs).Take(4);

似乎设计得不太好-结果肯定取决于所使用的数据库,但如果您通常只看到前四只猫,却从未见过任何狗,我也不会感到惊讶。

当您将它们放在一起时,它如何能够分辨出哪个
iAnimal
引用了哪个数据源?您能在SQL本身中做到这一点,并且能够区分这两个源吗?换句话说,如果您确实
选择了ID、Name、Age FROM Dogs UNION SELECT ID、Name、Age FROM Cats
,并且只查看了结果集,您是否能够区分每个记录的源?在NHibernate中,您只能在定义鉴别器的情况下使用继承。可能实体有类似的要求。此页面上没有此类行为的要求。严格来说,它是只读的。当你把它们放在一起时,它如何分辨哪个
iAnimal
引用了哪个数据源?您能在SQL本身中做到这一点,并且能够区分这两个源吗?换句话说,如果您确实
选择了ID、Name、Age FROM Dogs UNION SELECT ID、Name、Age FROM Cats
,并且只查看了结果集,您是否能够区分每个记录的源?在NHibernate中,您只能在定义鉴别器的情况下使用继承。可能实体有类似的要求。此页面上没有此类行为的要求。它是严格的只读的。我相信我试过这个,但是没有用。我会再试一次。。。敬请期待。我写的这个问题更多的是一个概念证明。我不想退回1000多件物品。我只是想先测试一下
.Concat
的功能。这个解决方案很有效,但是如果数据集很大怎么办?如果我记得的话,
ToList()
是一个贪婪的操作符。此解决方案将运行这两个查询。是否有可能操纵它只接触数据库一次?这可能不在这里也不在那里,但我并不完全明白这(不仅仅是这个答案,而是在这个场景中使用一个接口)如何简化或简化本来应该是
var query=db.Cats.Concat(db.Dogs)的内容
。我确信,除非使用继承,否则不可能将两个查询合并为一个查询。您真的需要一个查询吗?在很多情况下,我想不出这会有什么不同。如果你想要100只宠物,那就试着养100只狗吧
var model = _db.Cats.Concat<iAnimal>(_db.Dogs).Take(4);