Вы могли бы представить другую сторону ассоциации, что означает наборы ребер, которые начинаются в узле и заканчиваются в узле.Тогда вам не понадобится контекст базы данных в классе Node
:
class Edge
{
public int Id { get; set;}
public double Weight { get; set; }
[InverseProperty("OutgoingEdges")]
[Required]
public Node StartNode { get; set; }
[InverseProperty("IncomingEdges")]
[Required]
public Node EndNode { get; set; }
}
class Node
{
public int Id { get; set; }
public string Label { get; set; }
public ICollection<Edge> OutgoingEdges { get; set; }
public ICollection<Edge> IncomingEdges { get; set; }
public int EdgesFromThisNode
{
get { return OutgoingEdges != null ? OutgoingEdges.Count() : 0; }
}
}
или в конфигурации Fluent, если вам не нужны атрибуты в классе Edge
:
modelBuilder.Entity<Edge>()
.HasRequired(e => e.StartNode)
.WithMany(n => n.OutgoingEdges);
modelBuilder.Entity<Edge>()
.HasRequired(e => e.EndNode)
.WithMany(n => n.IncomingEdges);
Когда вы загружаете Node
, вы должны убедиться, что также загружен набор нужных вам ребер:
using (var graph = new Graph())
{
Node node = graph.Nodes.Include(n => n.OutgoingEdges)
.FirstOrDefault(n => n.Id == 1);
// node.EdgesFromThisNode would give now correct result
}
В качестве альтернативы вы можете пометить свои свойства навигации как virtual
, чтобы извлечь выгоду из ленивостиloading.
Примечание. Это решение полезно только в том случае, если вас действительно интересуют исходящие и входящие ребра узла.(Я ссылался в основном на эту часть вашего вопроса: «Если бы я каким-то образом мог связать все края или, что еще лучше, некоторые из ребер (выходящих из узла) с узлом ...») Если вы хотите толькоиметь число ребер, которые вы слишком много загружаете из базы данных (все объекты Edge).
Edit
Несколько ресурсов об EF4.1, особенно Code-First:
Пошаговое руководство по Code-First: http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-code-first-walkthrough.aspx
Учебник из 12 частей об EF 4.1: http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-1-introduction-and-model.aspx
Блог Мортезы Манави об ассоциациях иНаследование в Code-First: http://weblogs.asp.net/manavi/default.aspx
Страницы MSDN о EF 4.1: http://msdn.microsoft.com/en-us/library/gg696172%28v=vs.103%29.aspx
Несколько обучающих видео: http://msdn.microsoft.com/en-us/data/cc300162
Редактировать 2
Если вы хотите привязать только число ребер к виду, не загружая все объекты ребер, я бы рассмотрел работу с ViewModel, которая оборачивает сам узел и имеет дополнительное свойство:
public class NodeViewModel
{
public Node Node { get; set; }
public int NumberOfOutgoingEdges { get; set; }
}
Я бы оставил две коллекции навигации в классе Node (и повторнопереместить свойство EdgesFromThisNode
), но я бы не стал загружать коллекции для этого конкретного сценария привязки и вместо этого использовал бы проекцию в новый тип ViewModel:
using (var graph = new Graph())
{
NodeViewModel nodeViewModel = graph.Nodes
.Where(n => n.Id == 1)
.Select(n => new NodeViewModel()
{
Node = n,
NumberOfOutgoingEdges = n.OutgoingEdges.Count()
})
.FirstOrDefault();
// nodeViewModel.Node doesn't have the OutgoingEdges loaded now
}
Затем вы привязываете NodeViewModel
к вашему представлениюа не напрямую Node
.Это решение позволяет избежать внедрения контекста базы данных в класс вашей модели (что, на мой взгляд, очень противоречит идее POCO).