mirror of https://github.com/lidarr/Lidarr
Synced Marr with upstream
This commit is contained in:
parent
96990eabb3
commit
16425cdab6
|
@ -660,15 +660,19 @@ namespace Marr.Data
|
|||
// and multiple entities are created from each view record.
|
||||
foreach (EntityGraph lvl in graph)
|
||||
{
|
||||
// If is child relationship entity, and childrenToLoad are specified, and entity is not listed,
|
||||
// then skip this entity.
|
||||
if (childrenToLoad.Count > 0 && !lvl.IsRoot && !childrenToLoad.ContainsMember(lvl.Member)) // lvl.Member.Name
|
||||
if (lvl.IsParentReference)
|
||||
{
|
||||
// A child specified a circular reference to its previously loaded parent
|
||||
lvl.AddParentReference();
|
||||
}
|
||||
else if (childrenToLoad.Count > 0 && !lvl.IsRoot && !childrenToLoad.ContainsMember(lvl.Member))
|
||||
{
|
||||
// A list of relationships-to-load was specified and this relationship was not included
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lvl.IsNewGroup(reader))
|
||||
else if (lvl.IsNewGroup(reader))
|
||||
{
|
||||
// Create a new entity with the data reader
|
||||
var newEntity = mappingHelper.CreateAndLoadEntity(lvl.EntityType, lvl.Columns, reader, true);
|
||||
|
||||
// Add entity to the appropriate place in the object graph
|
||||
|
|
|
@ -43,7 +43,8 @@ namespace Marr.Data
|
|||
private GroupingKeyCollection _groupingKeyColumns;
|
||||
private Dictionary<string, EntityReference> _entityReferences;
|
||||
|
||||
public IList RootList { get; private set; }
|
||||
internal IList RootList { get; private set; }
|
||||
internal bool IsParentReference { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Recursively builds an entity graph of the given parent type.
|
||||
|
@ -68,12 +69,22 @@ namespace Marr.Data
|
|||
_entityType = entityType;
|
||||
_parent = parent;
|
||||
_relationship = relationship;
|
||||
IsParentReference = !IsRoot && AnyParentsAreOfType(entityType);
|
||||
if (!IsParentReference)
|
||||
{
|
||||
_columns = _repos.GetColumns(entityType);
|
||||
}
|
||||
|
||||
_relationships = _repos.GetRelationships(entityType);
|
||||
_children = new List<EntityGraph>();
|
||||
Member = relationship != null ? relationship.Member : null;
|
||||
_entityReferences = new Dictionary<string, EntityReference>();
|
||||
|
||||
if (IsParentReference)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new EntityGraph for each child relationship that is not lazy loaded
|
||||
foreach (Relationship childRelationship in this.Relationships)
|
||||
{
|
||||
|
@ -183,51 +194,12 @@ namespace Marr.Data
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the owning lists on many-to-many Children.
|
||||
/// Searches for a previously loaded parent entity and then sets that reference to the mapped Relationship property.
|
||||
/// </summary>
|
||||
/// <param name="entityInstance"></param>
|
||||
private void InitOneToManyChildLists(EntityReference entityRef)
|
||||
public void AddParentReference()
|
||||
{
|
||||
// Get a reference to the parent's the childrens' OwningLists to the parent entity
|
||||
for (int i = 0; i < Relationships.Count; i++)
|
||||
{
|
||||
Relationship relationship = Relationships[i];
|
||||
if (relationship.RelationshipInfo.RelationType == RelationshipTypes.Many)
|
||||
{
|
||||
try
|
||||
{
|
||||
IList list = (IList)_repos.ReflectionStrategy.CreateInstance(relationship.MemberType);
|
||||
_repos.ReflectionStrategy.SetFieldValue(entityRef.Entity, relationship.Member.Name, list);
|
||||
|
||||
// Save a reference to each 1-M list
|
||||
entityRef.AddChildList(relationship.Member.Name, list);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new DataMappingException(
|
||||
string.Format("{0}.{1} is a \"Many\" relationship type so it must derive from IList.",
|
||||
entityRef.Entity.GetType().Name, relationship.Member.Name),
|
||||
ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recursively adds primary key columns from contiguous child graphs with a one-to-one relationship type to the pKeys collection..
|
||||
/// </summary>
|
||||
/// <param name="pKeys"></param>
|
||||
/// <param name="entity"></param>
|
||||
private void AddOneToOneChildKeys(ColumnMapCollection pKeys, EntityGraph entity)
|
||||
{
|
||||
var oneToOneChildren = entity.Children
|
||||
.Where(c => c._relationship.RelationshipInfo.RelationType == RelationshipTypes.One);
|
||||
|
||||
foreach (var child in oneToOneChildren)
|
||||
{
|
||||
pKeys.AddRange(child.Columns.PrimaryKeys);
|
||||
AddOneToOneChildKeys(pKeys, child);
|
||||
}
|
||||
var parentReference = FindParentReference();
|
||||
_repos.ReflectionStrategy.SetFieldValue(_parent._entity, _relationship.Member.Name, parentReference);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -278,6 +250,68 @@ namespace Marr.Data
|
|||
}
|
||||
}
|
||||
|
||||
private bool AnyParentsAreOfType(Type type)
|
||||
{
|
||||
EntityGraph parent = _parent;
|
||||
while (parent != null)
|
||||
{
|
||||
if (parent._entityType == type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
parent = parent._parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private object FindParentReference()
|
||||
{
|
||||
var parent = this.Parent.Parent;
|
||||
while (parent != null)
|
||||
{
|
||||
if (parent._entityType == _relationship.MemberType)
|
||||
{
|
||||
return parent._entity;
|
||||
}
|
||||
|
||||
parent = parent.Parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the owning lists on many-to-many Children.
|
||||
/// </summary>
|
||||
/// <param name="entityInstance"></param>
|
||||
private void InitOneToManyChildLists(EntityReference entityRef)
|
||||
{
|
||||
// Get a reference to the parent's the childrens' OwningLists to the parent entity
|
||||
for (int i = 0; i < Relationships.Count; i++)
|
||||
{
|
||||
Relationship relationship = Relationships[i];
|
||||
if (relationship.RelationshipInfo.RelationType == RelationshipTypes.Many)
|
||||
{
|
||||
try
|
||||
{
|
||||
IList list = (IList)_repos.ReflectionStrategy.CreateInstance(relationship.MemberType);
|
||||
_repos.ReflectionStrategy.SetFieldValue(entityRef.Entity, relationship.Member.Name, list);
|
||||
|
||||
// Save a reference to each 1-M list
|
||||
entityRef.AddChildList(relationship.Member.Name, list);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new DataMappingException(
|
||||
string.Format("{0}.{1} is a \"Many\" relationship type so it must derive from IList.",
|
||||
entityRef.Entity.GetType().Name, relationship.Member.Name),
|
||||
ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of keys to group by.
|
||||
/// </summary>
|
||||
|
|
|
@ -12,10 +12,6 @@
|
|||
<AssemblyName>Marr.Data</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
|
|
Loading…
Reference in New Issue