From 28b47b415fd500f2e2fc2e8271346de632fefb49 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Tue, 21 May 2013 22:30:54 -0700 Subject: [PATCH] added condition to lazy loading of relationship objects no db calls will be made if foreign key is 0. --- Marr.Data/LazyLoaded.cs | 20 ++++--- Marr.Data/Mapping/RelationshipBuilder.cs | 5 +- .../Datastore/DatabaseRelationshipFixture.cs | 59 +++++++++++-------- .../Datastore/RelationshipExtensions.cs | 6 +- 4 files changed, 56 insertions(+), 34 deletions(-) diff --git a/Marr.Data/LazyLoaded.cs b/Marr.Data/LazyLoaded.cs index d492b18ba..db8f0c25d 100644 --- a/Marr.Data/LazyLoaded.cs +++ b/Marr.Data/LazyLoaded.cs @@ -70,14 +70,15 @@ namespace Marr.Data internal class LazyLoaded : LazyLoaded { private TParent _parent; - private Func _query; - private Func _dbCreator; - internal LazyLoaded(Func query) - : base() + private readonly Func _query; + private readonly Func _condition; + + internal LazyLoaded(Func query, Func condition = null) { _query = query; + _condition = condition; } public LazyLoaded(TChild val) @@ -107,11 +108,16 @@ namespace Marr.Data { if (!_isLoaded) { - using (IDataMapper db = _dbCreator()) + if (_condition != null && _condition(_parent)) { - _child = _query(db, _parent); - _isLoaded = true; + using (IDataMapper db = _dbCreator()) + { + _child = _query(db, _parent); + } } + + _child = default(TChild); + _isLoaded = true; } } diff --git a/Marr.Data/Mapping/RelationshipBuilder.cs b/Marr.Data/Mapping/RelationshipBuilder.cs index 1b27cdd87..9b71ce6a9 100644 --- a/Marr.Data/Mapping/RelationshipBuilder.cs +++ b/Marr.Data/Mapping/RelationshipBuilder.cs @@ -62,12 +62,13 @@ namespace Marr.Data.Mapping /// /// /// + /// condition in which a child could exist. eg. avoid call to db if foreign key is 0 or null /// - public RelationshipBuilder LazyLoad(Func query) + public RelationshipBuilder LazyLoad(Func query, Func condition = null) { AssertCurrentPropertyIsSet(); - Relationships[_currentPropertyName].LazyLoaded = new LazyLoaded(query); + Relationships[_currentPropertyName].LazyLoaded = new LazyLoaded(query, condition); return this; } diff --git a/NzbDrone.Core.Test/Datastore/DatabaseRelationshipFixture.cs b/NzbDrone.Core.Test/Datastore/DatabaseRelationshipFixture.cs index 09aa4d286..a24d791ee 100644 --- a/NzbDrone.Core.Test/Datastore/DatabaseRelationshipFixture.cs +++ b/NzbDrone.Core.Test/Datastore/DatabaseRelationshipFixture.cs @@ -4,6 +4,7 @@ using System.Linq; using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; +using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Qualities; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Tv; @@ -72,29 +73,41 @@ namespace NzbDrone.Core.Test.Datastore loadedSeries.Covers.Value.Should().HaveSameCount(covers); }*/ -// [Test] -// public void one_to_one() -// { -// var episode = Builder.CreateNew() -// .With(c => c.Id = 0) -// .Build(); -// -// Db.Insert(episode); -// -// -// var history = Builder.CreateNew() -// .With(c => c.Id = 0) -// .With(c => c.EpisodeId = episode.Id) -// .With(c => c.Quality = new QualityModel()) -// .Build(); -// -// Db.Insert(history); -// -// var loadedEpisode = Db.Single().Episode.Value; -// -// loadedEpisode.Should().NotBeNull(); -// loadedEpisode.ShouldHave().AllProperties().But(c => c.SeriesTitle).EqualTo(episode); -// } + [Test] + public void one_to_one() + { + var episodeFile = Builder.CreateNew() + .BuildNew(); + + Db.Insert(episodeFile); + + var episode = Builder.CreateNew() + .With(c => c.EpisodeFileId = episodeFile.Id) + .BuildNew(); + + Db.Insert(episode); + + + + + + var loadedEpisodeFile = Db.Single().EpisodeFile.Value; + + loadedEpisodeFile.Should().NotBeNull(); + loadedEpisodeFile.ShouldHave().AllProperties().But(c => c.DateAdded).EqualTo(episodeFile); + } + + [Test] + public void one_to_one_should_not_query_db_if_foreign_key_is_zero() + { + var episode = Builder.CreateNew() + .With(c => c.EpisodeFileId = 0) + .BuildNew(); + + Db.Insert(episode); + + Db.Single().EpisodeFile.Value.Should().BeNull(); + } [Test] diff --git a/NzbDrone.Core/Datastore/RelationshipExtensions.cs b/NzbDrone.Core/Datastore/RelationshipExtensions.cs index 1f32aee74..1d82cb6ed 100644 --- a/NzbDrone.Core/Datastore/RelationshipExtensions.cs +++ b/NzbDrone.Core/Datastore/RelationshipExtensions.cs @@ -13,8 +13,10 @@ namespace NzbDrone.Core.Datastore where TChild : ModelBase { return relationshipBuilder.For(portalExpression.GetMemberName()) - .LazyLoad((db, parent) => db.Query() - .SingleOrDefault(c => c.Id == childIdSelector(parent))); + .LazyLoad( + query: (db, parent) => db.Query().SingleOrDefault(c => c.Id == childIdSelector(parent)), + condition: parent => childIdSelector(parent) > 0 + ); }