LINQ:“Union或Concat中的类型构造不兼容。”

时间:2013-06-23 03:55:19

标签: c# asp.net linq linq-to-sql notsupportedexception

我对ASP.NET和LINQ比较陌生,但我遇到了一种非常奇怪的行为,几乎让我发疯。我找到了一些关于标题中提到的错误的讨论,但似乎没有一个适合我的问题。请查看对象关系设计器中的以下快照:

Screenshot from ORD, showing the data model

如您所见,Relation代表两个Anchor的连接。因此,为表Relation定义了两个外键:Relation.AnchorIDFrom => Anchor.AnchorIDRelation.AnchorIDTo => Anchor.AnchorID。这些列都不可为空。我现在的目标是,给定一个锚点ID列表,以检索这些锚点参与的所有Relation个。这是方法:

[WebMethod]
public string GetRelations(String token, List<Guid> anchorIDs)
{
    JavaScriptSerializer js = new JavaScriptSerializer();
    LinkItCoreDataContext dc = new LinkItCoreDataContext();

    IQueryable relationQry =
        from anchor in dc.Anchors
        where anchorIDs.Contains(anchor.AnchorID)
        //stupid names because object relational designer
        //does not seem to support custom names:
        from relation in anchor.Relations.Union(anchor.Relations1)
        select new
        {
            relationID = relation.RelationID,
            anchorIDFrom = relation.AnchorIDFrom,
            anchorIDTo = relation.AnchorIDTo,
            relationTypes = from type in relation.RelationTypes
                            //stupid names again:
                            select type.RelationType1
        };
    return js.Serialize(relationQry);//Here's where the error occurs
}

在运行时,这给了我一个NotSupportedException说明联盟或Concat中的类型构造不兼容。我认为这很奇怪,因为表达式anchor.Relations.Union(anchor.Relations1)应该合并两个在语法意义上完全相同的东西。如果我将关键行更改为from relation in anchor.Relationsfrom relation in anchor.Relations1,一切正常。此外,添加ToList()(有时被称为解决方案)不会改变任何内容。

我错过了什么?

3 个答案:

答案 0 :(得分:1)

我尝试了类似的情况,并在实体框架中得到相同的错误,完全相同的查询运行正常。所以我认为你在这里遇到了一个错误(或“不支持的功能”),你可能需要解决它。你可以通过改变查询来做到这一点:

var relationQry =
      from relation in anchor.Relations
      where anchorIDs.Contains(relation.AnchorIDTo) 
         || anchorIDs.Contains(relation.AnchorIDFrom)
      select new
      {
          relationID = relation.RelationID,
          anchorIDFrom = relation.AnchorIDFrom,
          anchorIDTo = relation.AnchorIDTo,
          relationTypes = from type in relation.RelationTypes
                          select type.RelationType1
      };

顺便说一句:您可以通过选择设计器中的关联及其子属性的名称来更改“愚蠢的名字”:)。

答案 1 :(得分:1)

我遇到了同样的问题。 最终我解决了这个问题。

看来,即使结果类型相等,使用嵌套关系也会 导致错误。

我为解决这个问题所做的是:

我这样定义了DataLoadOptions:

var lo = new DataLoadOptions();

lo.LoadWith<Type>(t => t.NESTEDTYPE); // "t" is the database object in this scenario.
lo.LoadWith<Type>(t => t.NESTEDTYPE2);
lo.LoadWith<Type>(t => t.NESTEDTYPE3);

// etc.

dc.LoadOptions = lo;

对于每种嵌套类型,您都必须指定一个loadwith。 您只能在每个“有效”数据上下文上一次分配加载选项。

我希望您能够解决您的问题!

答案 2 :(得分:0)

你试过这个:

from relation in anchor.Relations.Concat(anchor.Relations1)

from relation in anchor.Relations.Concat(anchor.Relations1).Distinct()

第二个应该在功能上与Union相同,但我不相信它是你想要的,如果它可能会给出更好的错误信息。