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

时间:2013-01-08 19:37:27

标签: c# asp.net-mvc linq

我正在处理一个应用程序的一部分,该应用程序只是从数据库中提取信息并将其显示给用户。为简单起见,我们假设我有一个包含两个表CatsDogs的数据库。两个表都有手动分配的主键,并且从不重复/重叠。我想要实现的目标是执行1个LINQ查询,concat两个表。

我最近询问了this关于在代码中手动创建的两个对象集合LINQ concatCats上执行Dogs的问题。我建议阅读上一个问题,因为它会给这个问题提供很多见解。

我希望使用接口的原因是为了简化我的查询。我目前有一个解决方案.Select我需要的每个列都是匿名类型。这适用于此实例,但会使用包含我正在使用的数据的页面。

上一个问题和这个问题之间的不同之处在于我试图从数据库中提取这些动物。根据我的分析,似乎.NETEntity Framework无法将我的database与我的interface

相关联

模型(来自旧问题)

public interface iAnimal
{
    string name { get; set; }
    int age { get; set; }
}
public class Dog :iAnimal
{
    public string name { get; set; }
    public int age { get; set; }
}
public class Cat:iAnimal
{
    public string name { get; set; }
    public int age { get; set; }
}

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

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

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

没有协方差:

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

System.NotSupportedException: Unable to cast the type 'Test.Models.Cat' to type 'Test.Interfaces.iAnimals'. LINQ to Entities only supports casting Entity Data Model primitive types.

从上面的错误中,看起来我无法使用接口与数据库交互,因为它没有映射到任何特定的表。

非常感谢任何见解。感谢

修改 为了回应@Reed Copsey,使用您的解决方案,我得到了与我的示例without covariance相同的错误。我尝试更改视图的类型以匹配错误建议的内容,这会导致此错误

System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1[Test.Interfaces.iAnimal]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[Test.Models.Cat]'.

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

var pets = dogs.Cast<IPet>().Concat(cats).ToList();

另请注意您的查询

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

似乎没有真正精心设计 - 结果肯定取决于所使用的数据库,但如果您通常只获得前四只猫并且从未看到任何狗,我不会感到惊讶。