【问题标题】:Linq and SubSonic - returning nested complex typesLinq 和 SubSonic - 返回嵌套的复杂类型
【发布时间】:2010-07-15 11:43:33
【问题描述】:

我是 SubSonic 的新手,对 LINQ 也相当陌生,所以我只是想把一个小应用程序放在一起。

我已经将模板全部排序并且运行良好,但是我在使用这个 LINQ 语句时遇到了一些麻烦(稍微简化一下,真正的语句还有一些其他的连接,但它们不会影响这个特定的问题,所以为简洁起见,我已将其删除):

var addresses = from address in Database.Addresses.All()
                           select new Address()
                               {
                                   MyNestedType = new NestedType()
                                       {
                                           Field1 = address.ADDR1
                                       }
                               };

如果我执行此语句,当我尝试枚举结果时,我会收到错误Invalid cast from 'System.String' to 'NestedType'。

我可能忽略了显而易见的事情,但我看不到我要求进行此类转换的任何地方。

Field1 和 address.ADDR1 都是字符串。

任何想法我做错了什么?

编辑:

我对此进行了重新审视,为了提供更多信息,我使用 SimpleRepository 和一个 SQLite 数据库创建了一个小而完整的示例来演示该问题。使用 SimpleRepository 我得到的错误是不同的(序列不包含元素),但结果是一样的。这是完整的代码:

 public class DatabaseAddress
 {
     public int Id { get; set; }
     public string Address1 { get; set; }
 }

 public class Address
 {
     public NestedType MyNestedType;
 }

 public class NestedType
 {
     public string Field1 { get; set; }
 }

 static class Program
 {
    [STAThread]
    static void Main()
    {
         var repo = new SimpleRepository("Db", SimpleRepositoryOptions.RunMigrations);
         DatabaseAddress address1 = new DatabaseAddress();
         address1.Address1 = "Test";
         repo.Add(address1);
         var all = repo.All<DatabaseAddress>();
         var addresses = from address in repo.All<DatabaseAddress>()
                         select new Address { MyNestedType = new NestedType { Field1 = address.Address1 } };
    }
 }

在此示例中,all 包含添加到数据库中的对象,但 addresses 返回“序列不包含任何元素”。

如果我在 select 语句中使用匿名类型而不是具体类型,它会起作用。

我的知识显然存在差距;任何帮助表示赞赏。

【问题讨论】:

  • 您的代码肯定有其他问题,根据提供的信息无法确定问题所在。基于这个 sn-p,唯一的可能是 Field1 是 NestedType 类型。既然你说它是一个字符串,那么你没有给我们足够的实际代码来解决这个问题。
  • 感谢您的评论。我认为我已经添加了足够的信息,因为实际上没有比我发布的更多的代码。我已经编辑了我的原始帖子并添加了一个完整的示例。

标签: linq linq-to-sql subsonic subsonic3


【解决方案1】:

请看我的问答here。

以下是测试是否是同一问题的方法:

在您发布的示例代码中,将 NestedType 中的 Field1 更改为 Address1。重新运行您的样品。如果它有效,同样的问题和我在链接问题中回答的修复应该可以为您解决。

【讨论】:

  • 在这种情况下似乎并没有解决它,但无论如何我会调查一个有趣的线索,谢谢。
  • 这几乎是正确的 - MyNestedType 也必须重命名以匹配类名,反之亦然。实际上,我只是在 Field1 不变的情况下尝试了它,它可以工作,所以只需更改 MyNestedType 以匹配类名(或将类重命名为 MyNestedType)。
  • 啊废话,没关系,它不起作用,现在我得到了原始错误:从'System.String'到'SubSonicTest.NestedType'的无效转换。我忘了把它从匿名类型改回来。哦。
【解决方案2】:

您必须调用 ToList(),否则 SubSonic 提供程序会尝试使用 MyNestedType 执行某些操作,并且它在数据库中不存在。

var addresses = from address in repo.All<DatabaseAddress>().ToList()
                        select new Address { MyNestedType = new NestedType { Field1 = address.Address1 } };

更新:如果您之后调用 ToList 也可以使用,即:

addresses.ToList().ForEach(address => Console.WriteLine("Address.MyNestedType.Field1 = {0}", address.MyNestedType.Field1));

我猜 SubSonic 查询提供程序中存在一个错误,因为它确实适用于匿名类型,正如您所提到的。

【讨论】:

  • 这对我有用。我现在可以看到我哪里出错了。谢谢。
  • 这不会导致将 where 子句和排序等转换为 SQL,因为在应用任何其他可翻译子句之前,将通过调用 ToList 来获取和枚举整个表?
  • 您可以在有意义的情况下调用 ToList,就在导致问题的投影之前:即:var address = (from address in repo.All() where address.Id new Address { NestedType = new NestedType { Address1 = address.Address1 } });
  • 有趣,我想我会把它归结为 Subsonic 错误并相应地重组我的代码。感谢您的帮助。
【解决方案3】:

试试这个

var nestedTypes= from address in Database.Addresses.All()
                select new NestedType()
                {
                 Field1 = address.ADDR1
                };

【讨论】:

  • 这并没有实现我所追求的,这是一种嵌套在另一种中的类型。
猜你喜欢
  • 2021-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-22
相关资源
最近更新 更多