2012-10-01 47 views
5

使用实体框架LINQ,我想为每个父表返回一个父类,并使用多个具体实现之一在父类上填充其类型为接口的属性的界面。基于父表中字段的值,应该在查询时确定具体的实现。EF4无法将具体类型转换为接口

在一个非常简单的例子中,我有3个表格和3个相应的POCO。

例如起见简单的表格

Three Tables: Master and two children

简单的类例如起见

internal interface IConfiguration 
{ 
} 

internal class ConfigurationContainer 
{ 
    public IConfiguration Config { get; set; } 
} 

internal class ConfigurationSouth : IConfiguration 
{ 
} 

internal class ConfigurationNorth : IConfiguration 
{ 
} 

不幸的是,我通过所有父成果环,并确定哪些子查询在循环内部使用。有些东西这个块。

foreach (var configMaster in db.ConfigMasters.ToList()) 
{ 
    var configContainer = new ConfigurationContainer(); 
    if (configMaster.IsNorth) 
     configContainer.Config = (from x in db.ConfigNorths 
          select new ConfigurationNorth()) 
             .FirstOrDefault(); 
    else 
     configContainer.Config = (from x in db.ConfigSouths 
          select new ConfigurationSouth()) 
             .FirstOrDefault(); 
} 

循环浏览每条父记录以执行子查询并不理想。我真的很喜欢EF LINQ在一次访问数据库时执行查询以及对我的POCO进行预测。

我想出了这个LINQ来查询一次旅行中的数据库并返回投影对象,这样Config属性就会在查询时间由两个子查询之一填充。虽然它编译,但它在运行时引发异常。

using (var db = new Entities()) 
{ 
    var qry = from cfgMaster in db.ConfigMasters 
       let configNorth = (from x in db.ConfigNorths 
            select new ConfigurationNorth()) 
        .FirstOrDefault() 
       let configSouth = (from x in db.ConfigSouths 
            select new ConfigurationSouth()) 
        .FirstOrDefault() 
       select new ConfigurationContainer() 
        { 
         Config = cfgMaster.IsNorth ? configNorth : (IConfiguration) configSouth 
        }; 

    var results = qry.ToList(); 
} 

异常

未处理的异常:System.NotSupportedException:无法铸 类型 'EFTest.ConfigurationNorth' 为类型 'EFTest.IConfiguration'。实体仅支持投射实体数据模型基元类型。

+0

只有当您让两个类都从模型的基类中派生出来时,才能这样做。 –

+0

:(不幸的是,看起来你是对的,如果你将其作为答案发布,我会接受它。 –

回答

1

实体框架没有(还?)以这种方式支持接口的使用,这基本上是因为接口没有(也不能)注册到模型中。你想要的只有当你让两个类都来自模型的基类时才可能。

相关问题