生成两个IEnumerables并组合它们

时间:2013-12-06 01:01:28

标签: c# linq entity-framework ienumerable graph-theory

我很难写这个标题,我不确定它是否足够好。

我正在制作路由应用程序。我正在使用实体框架。因为我的地图是无向图,所以我需要从数据库中检索两次边(A-> B,B-> A),它们只存储为(A-> B)。

到目前为止,我有这个:

public IList<Edge> GetBatteryCenterEdges(string name)
{
    var query =
        from edges in context.Edge
        where (edges.BatteryStation.name.Equals(name) || edges.BatteryStation1.name.Equals(name))
        select edges;

    return query.ToList();
}

但这只会返回A-> B。

我必须注意到我是C#和LINQ的新手。

我尝试过:

IEnumerable<Edge> test = query.Select(x => new Edge { BatteryStation = x.BatteryStation1, BatteryStation1 = x.BatteryStation });

BatteryStationBatteryStation1基本上是顶点)

然后我试着做

query.Union(test)

但是这不会返回任何反转的Edge

所以我尝试返回test,这会导致:

The entity or complex type 'CarBatteryModel.Edge' cannot be constructed in a LINQ to Entities query.

如何以最佳方式从数据库中反转这些Edge个对象?

我的课程:

Edge来自ET:

public partial class Edge
{
    public virtual BatteryStation BatteryStation { get; set; }
    public virtual BatteryStation BatteryStation1 { get; set; }
}

BatteryCenter继承自ET的BatteryStation

public class BatteryCenter : BatteryStation
{
    public IList<Edge> Edgelist;

    public BatteryCenter()
    {
        Edgelist = new List<Edge>();
    }
}

1 个答案:

答案 0 :(得分:2)

我会使用方法语法:

var query = context.Edge.Where(edge=>edge.BatteryStation.name.Equals(name) ||
                                     edge.BatteryStation1.name.Equals(name))
                   .AsEnumerable()
                   .SelectMany(edge => new []{ edge,
                                            new Edge{
                                             BatteryStation = edge.BatteryStation1,
                                             BatteryStation1 = edge.BatteryStation
                                            }
                               });
return query.ToList();

<强>更新

尝试建设Expression tree

var query = context.Edge.Where(edge=>edge.BatteryStation.name.Equals(name) ||
                                     edge.BatteryStation1.name.Equals(name));
var edgeParam = Expression.Param(typeof(Edge),"edge");
var edgeBA = Expression.New(typeof(Edge));
var bind1 = Expression.Bind(typeof(Edge).GetProperty("BatteryStation"),
                            Expression.Property(edgeParam, "BatteryStation1"));
var bind2 = Expression.Bind(typeof(Edge).GetProperty("BatteryStation1"),
                            Expression.Property(edgeParam, "BatteryStation"));
var edgeBAInit = Expression.MemberInit(edgeBA, bind1, bind2);
var edgeArray = Expression.NewArrayInit(typeof(Edge),edgeParam, edgeBAInit);
var selectManyLambda = Expression.Lambda<Func<Edge,IEnumerable<Edge>>>(
                                  edgeArray, edgeParam);
return query.SelectMany(selectManyLambda).ToList();