【问题标题】:LINQ and web service cannot return anonymous types, and you cannot construct an object in a query?LINQ 和 web 服务不能返回匿名类型,不能在查询中构造对象?
【发布时间】:2013-07-23 20:53:01
【问题描述】:
  1. Web 服务不能返回匿名类型。
  2. 如果您通过数据上下文使用类构建 LINQ 查询...您无法在查询中构造这些类的实例。

我为什么要这样做?假设我想加入三个“表”或对象集。我有三个相互具有外键的项目。并且说最低,最详细的这些是由一个类表示的,该类具有来自其他两个字段的字段来表示这些数据。在我的 LINQ 查询中,我想返回一个最低、最详细的类的列表。这是我决定“将一些表连接在一起”并通过 LINQ 将每个表中的数据通过 WebService 返回到 SQL 的一种方式。这可能是不好的做法。我当然不喜欢将额外的属性添加到最低级别的类中。

考虑这样的事情......(请忽略命名约定,它们是由内部考虑驱动的)也出于某种原因我需要为连接实例化一个匿名类型......我不知道为什么会这样。 ..如果我不这样做,我会收到错误...

from su in _dataContext.GetTable<StateUpdate>()
                  join sfs in _dataContext.GetTable<SystemFacetState>()
                    on new { su.lngSystemFacetState } equals new { lngSystemFacetState = sfs.lngSystemFacetState }
                  join sf in _dataContext.GetTable<SystemFacet>()
                    on new { sfs.lngSystemFacet } equals new { lngSystemFacet = sf.lngSystemFacet }
                   join s in _dataContext.GetTable<System>()
                    on new { sf.lngSystem } equals new {lngSystem = s.lngSystem}
                  select new
                  {
                      lngStateUpdate = su.lngStateUpdate,
                      strSystemFacet = sf.strSystemFacet,
                      strSystemFacetState = sfs.strSystemFacetState,
                      dtmStateUpdate = su.dtmStateUpdate,
                      dtmEndTime = su.dtmEndTime,
                      lngDuration = su.lngDuration,
                      strSystem = s.strSystem
                  }
                  ).ToList();

请注意,我必须构建由每种类型的片段组成的匿名类型。然后我必须做这样的事情......(将其转换为已知类型以通过网络服务传输)

result = new List<StateUpdate>(from a in qr select(new StateUpdate 
{
    lngStateUpdate = a.lngStateUpdate,
    strSystemFacet = a.strSystemFacet,
    strSystemFacetState = a.strSystemFacetState,
    dtmStateUpdate = a.dtmStateUpdate,
    dtmEndTime = a.dtmEndTime,
    lngDuration = a.lngDuration,
    strSystem = a.strSystem
}));

这太可怕了。也许我已经造成了一个可怕的混乱。如果我在这里偏离轨道,请引导我走向光明。当我将所有这些“未映射”属性添加到 StateUpdate 类时,我觉得我在这里遗漏了一些基本的东西。

我希望有人能看到我在这里所做的事情,以便我能找到更好的方法。

【问题讨论】:

  • 如果您在原始查询中创建新的StatusUpdate 实例而不是匿名类型的对象,您会收到什么错误?
  • 不允许显式构造实体类型。这在论坛上到处都是。这里也有一个更大的问题......我应该使用这样的实体吗?我在状态更新中拥有所有这些属性,例如 strSystem,它属于我要返回的系统,但我在更新中有它以使用更新作为传输对象。我想这是 DTO 中的 T。
  • 这就是创建 DTO 的目的。打包相关数据并将其发送出去以进行解包/使用。
  • 当您说 DTO 时,您指的是 DTO 还是特定技术(如 EF)中的 DTO 的概念?

标签: asp.net linq web-services linq-to-sql anonymous-types


【解决方案1】:

您可以创建一个“dto”类,它只包含您需要返回并填充它的属性,而不是匿名对象:

public class Result
{
    public string lngStateUpdate
    {
        get;
        set;
    }

    ... // other properties
}

然后像这样使用它:

from su in _dataContext.GetTable<StateUpdate>()
...
select new Result
{
    lngStateUpdate = su.lngStateUpdate,
    ... // other properties
}

吹毛求疵的注意事项 - 请放弃匈牙利符号和骆驼外壳的属性:)

【讨论】:

  • 是的,这就是我自己想出的答案。需要睡在上面。我讨厌我在问题中暗示的符号。我相信我办公室的某个人会看到这个,但没关系。在我们的案例中,这种表示法的原因在某种程度上是合理的,因为我们与工业系统交谈时事情变得更加倾斜......我们并不总是拥有接口的奢侈,尽管以一种显然是 CLS 类型的方式。不管它是我无法控制的符号。
【解决方案2】:

我认为答案是创建另一个对象作为 DTO。此对象不会映射到数据上下文,并且可以包含跨映射对象的字段。这解决了映射对象中重复属性的问题,并允许在查询中实例化 DTO 类,因为它没有映射。

仅供参考:关于连接的问题 - 我重新审视了它,我想我之前可能已经切换了连接的内部和外部组件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    • 2016-05-14
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多