diff options
| author | Tim Hobbs <jesus.tesh@gmail.com> | 2014-03-13 06:26:20 -0700 |
|---|---|---|
| committer | Tim Hobbs <jesus.tesh@gmail.com> | 2014-03-13 06:26:20 -0700 |
| commit | 9e33966ee120134d89f7aa21204b7ffc814dd29a (patch) | |
| tree | 297982b6cd4269ada15d93cec859b7cba27c0c1a /MediaBrowser.Controller/Entities | |
| parent | dd4a1ff4b50f58c27af223202454f80d45de4af1 (diff) | |
| parent | b7bcc2450694105de9f9fc8cc07d2cfc4d9d7c96 (diff) | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'MediaBrowser.Controller/Entities')
| -rw-r--r-- | MediaBrowser.Controller/Entities/Audio/Audio.cs | 18 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Audio/MusicArtist.cs | 11 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Audio/MusicGenre.cs | 18 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/BaseItem.cs | 13 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/BasePluginFolder.cs | 15 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Folder.cs | 70 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/GameGenre.cs | 17 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Genre.cs | 18 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/IHasImages.cs | 6 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/IItemByName.cs | 38 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/LinkedChild.cs | 10 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Person.cs | 17 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Studio.cs | 18 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/UserRootFolder.cs | 3 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Year.cs | 29 |
15 files changed, 159 insertions, 142 deletions
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 73e276f3b..8eb6236d1 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -66,6 +66,24 @@ namespace MediaBrowser.Controller.Entities.Audio /// <value>The artist.</value> public List<string> Artists { get; set; } + [IgnoreDataMember] + public List<string> AllArtists + { + get + { + var list = new List<string>(); + + if (!string.IsNullOrEmpty(AlbumArtist)) + { + list.Add(AlbumArtist); + } + list.AddRange(Artists); + + return list; + + } + } + /// <summary> /// Gets or sets the album. /// </summary> diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 11cf441f7..0a5d8eec0 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -1,12 +1,10 @@ using MediaBrowser.Common.Progress; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; @@ -17,9 +15,6 @@ namespace MediaBrowser.Controller.Entities.Audio /// </summary> public class MusicArtist : Folder, IMetadataContainer, IItemByName, IHasMusicGenres, IHasDualAccess, IHasTags, IHasProductionLocations, IHasLookupInfo<ArtistInfo> { - [IgnoreDataMember] - public List<ItemByNameCounts> UserItemCountList { get; set; } - public bool IsAccessedByName { get; set; } /// <summary> @@ -65,7 +60,6 @@ namespace MediaBrowser.Controller.Entities.Audio public MusicArtist() { - UserItemCountList = new List<ItemByNameCounts>(); Tags = new List<string>(); ProductionLocations = new List<string>(); } @@ -230,5 +224,10 @@ namespace MediaBrowser.Controller.Entities.Audio return info; } + + public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) + { + return inputItems.OfType<IHasArtist>().Where(i => i.HasArtist(Name)).Cast<BaseItem>(); + } } } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index 5e1d4c3c9..bce9da4d1 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -1,7 +1,6 @@ -using System.Runtime.Serialization; -using MediaBrowser.Model.Dto; -using System; +using System; using System.Collections.Generic; +using System.Linq; namespace MediaBrowser.Controller.Entities.Audio { @@ -10,11 +9,6 @@ namespace MediaBrowser.Controller.Entities.Audio /// </summary> public class MusicGenre : BaseItem, IItemByName { - public MusicGenre() - { - UserItemCountList = new List<ItemByNameCounts>(); - } - /// <summary> /// Gets the user data key. /// </summary> @@ -24,9 +18,6 @@ namespace MediaBrowser.Controller.Entities.Audio return "MusicGenre-" + Name; } - [IgnoreDataMember] - public List<ItemByNameCounts> UserItemCountList { get; set; } - /// <summary> /// Returns the folder containing the item. /// If the item is a folder, it returns the folder itself @@ -51,5 +42,10 @@ namespace MediaBrowser.Controller.Entities.Audio return false; } } + + public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) + { + return inputItems.Where(i => (i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase)); + } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 923673bd8..23f8ac31a 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -125,6 +125,15 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] + public virtual bool IsHidden + { + get + { + return false; + } + } + + [IgnoreDataMember] public virtual bool IsOwnedItem { get @@ -1175,7 +1184,7 @@ namespace MediaBrowser.Controller.Entities return GetImageInfo(type, imageIndex) != null; } - public void SetImagePath(ImageType type, int index, FileInfo file) + public void SetImagePath(ImageType type, int index, FileSystemInfo file) { if (type == ImageType.Chapter) { @@ -1330,7 +1339,7 @@ namespace MediaBrowser.Controller.Entities /// <param name="images">The images.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> /// <exception cref="System.ArgumentException">Cannot call AddImages with chapter images</exception> - public bool AddImages(ImageType imageType, IEnumerable<FileInfo> images) + public bool AddImages(ImageType imageType, IEnumerable<FileSystemInfo> images) { if (imageType == ImageType.Chapter) { diff --git a/MediaBrowser.Controller/Entities/BasePluginFolder.cs b/MediaBrowser.Controller/Entities/BasePluginFolder.cs index 8f7071000..29d66718c 100644 --- a/MediaBrowser.Controller/Entities/BasePluginFolder.cs +++ b/MediaBrowser.Controller/Entities/BasePluginFolder.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Model.Entities; - + namespace MediaBrowser.Controller.Entities { /// <summary> @@ -8,18 +7,6 @@ namespace MediaBrowser.Controller.Entities /// </summary> public abstract class BasePluginFolder : Folder, ICollectionFolder, IByReferenceItem { - /// <summary> - /// Gets or sets the type of the location. - /// </summary> - /// <value>The type of the location.</value> - public override LocationType LocationType - { - get - { - return LocationType.Virtual; - } - } - protected BasePluginFolder() { DisplayMediaType = "CollectionFolder"; diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 627f657ab..ee371680e 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -264,7 +264,7 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public IEnumerable<BaseItem> Children { - get { return ActualChildren; } + get { return ActualChildren.Where(i => !i.IsHidden); } } /// <summary> @@ -745,9 +745,9 @@ namespace MediaBrowser.Controller.Entities var list = new List<BaseItem>(); - AddChildrenToList(user, includeLinkedChildren, list, false, null); + var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, false, null); - return list; + return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list; } /// <summary> @@ -905,13 +905,6 @@ namespace MediaBrowser.Controller.Entities /// <returns>BaseItem.</returns> private BaseItem GetLinkedChild(LinkedChild info) { - if (string.IsNullOrEmpty(info.Path)) - { - throw new ArgumentException("Encountered linked child with empty path."); - } - - BaseItem item = null; - // First get using the cached Id if (info.ItemId.HasValue) { @@ -920,20 +913,19 @@ namespace MediaBrowser.Controller.Entities return null; } - item = LibraryManager.GetItemById(info.ItemId.Value); - } + var itemById = LibraryManager.GetItemById(info.ItemId.Value); - // If still null, search by path - if (item == null) - { - item = LibraryManager.RootFolder.FindByPath(info.Path); + if (itemById != null) + { + return itemById; + } } + var item = FindLinkedChild(info); + // If still null, log if (item == null) { - Logger.Warn("Unable to find linked item at {0}", info.Path); - // Don't keep searching over and over info.ItemId = Guid.Empty; } @@ -946,6 +938,43 @@ namespace MediaBrowser.Controller.Entities return item; } + private BaseItem FindLinkedChild(LinkedChild info) + { + if (!string.IsNullOrEmpty(info.Path)) + { + var itemByPath = LibraryManager.RootFolder.FindByPath(info.Path); + + if (itemByPath == null) + { + Logger.Warn("Unable to find linked item at path {0}", info.Path); + } + + return itemByPath; + } + + if (!string.IsNullOrWhiteSpace(info.ItemName) && !string.IsNullOrWhiteSpace(info.ItemType)) + { + return LibraryManager.RootFolder.RecursiveChildren.FirstOrDefault(i => + { + if (string.Equals(i.Name, info.ItemName, StringComparison.OrdinalIgnoreCase)) + { + if (string.Equals(i.GetType().Name, info.ItemType, StringComparison.OrdinalIgnoreCase)) + { + if (info.ItemYear.HasValue) + { + return info.ItemYear.Value == (i.ProductionYear ?? -1); + } + return true; + } + } + + return false; + }); + } + + return null; + } + protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken) { var changesFound = false; @@ -1106,5 +1135,10 @@ namespace MediaBrowser.Controller.Entities return GetRecursiveChildren(user).Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual) .All(i => i.IsUnplayed(user)); } + + public IEnumerable<BaseItem> GetHiddenChildren() + { + return ActualChildren.Where(i => i.IsHidden); + } } } diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 3a3c575cd..825468954 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -1,16 +1,11 @@ -using MediaBrowser.Model.Dto; +using System; using System.Collections.Generic; -using System.Runtime.Serialization; +using System.Linq; namespace MediaBrowser.Controller.Entities { public class GameGenre : BaseItem, IItemByName { - public GameGenre() - { - UserItemCountList = new List<ItemByNameCounts>(); - } - /// <summary> /// Gets the user data key. /// </summary> @@ -20,9 +15,6 @@ namespace MediaBrowser.Controller.Entities return "GameGenre-" + Name; } - [IgnoreDataMember] - public List<ItemByNameCounts> UserItemCountList { get; set; } - /// <summary> /// Returns the folder containing the item. /// If the item is a folder, it returns the folder itself @@ -47,5 +39,10 @@ namespace MediaBrowser.Controller.Entities return false; } } + + public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) + { + return inputItems.Where(i => (i is Game) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase)); + } } } diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index c15ca0aa2..05442f2b7 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -1,6 +1,7 @@ -using MediaBrowser.Model.Dto; +using MediaBrowser.Controller.Entities.Audio; +using System; using System.Collections.Generic; -using System.Runtime.Serialization; +using System.Linq; namespace MediaBrowser.Controller.Entities { @@ -9,11 +10,6 @@ namespace MediaBrowser.Controller.Entities /// </summary> public class Genre : BaseItem, IItemByName { - public Genre() - { - UserItemCountList = new List<ItemByNameCounts>(); - } - /// <summary> /// Gets the user data key. /// </summary> @@ -23,9 +19,6 @@ namespace MediaBrowser.Controller.Entities return "Genre-" + Name; } - [IgnoreDataMember] - public List<ItemByNameCounts> UserItemCountList { get; set; } - /// <summary> /// Returns the folder containing the item. /// If the item is a folder, it returns the folder itself @@ -50,5 +43,10 @@ namespace MediaBrowser.Controller.Entities return false; } } + + public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) + { + return inputItems.Where(i => !(i is Game) && !(i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase)); + } } } diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs index 8e66605dd..bac226369 100644 --- a/MediaBrowser.Controller/Entities/IHasImages.cs +++ b/MediaBrowser.Controller/Entities/IHasImages.cs @@ -62,7 +62,7 @@ namespace MediaBrowser.Controller.Entities /// <param name="type">The type.</param> /// <param name="index">The index.</param> /// <param name="file">The file.</param> - void SetImagePath(ImageType type, int index, FileInfo file); + void SetImagePath(ImageType type, int index, FileSystemInfo file); /// <summary> /// Determines whether the specified type has image. @@ -129,7 +129,7 @@ namespace MediaBrowser.Controller.Entities /// <param name="imageType">Type of the image.</param> /// <param name="images">The images.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> - bool AddImages(ImageType imageType, IEnumerable<FileInfo> images); + bool AddImages(ImageType imageType, IEnumerable<FileSystemInfo> images); /// <summary> /// Determines whether [is save local metadata enabled]. @@ -180,7 +180,7 @@ namespace MediaBrowser.Controller.Entities /// <param name="item">The item.</param> /// <param name="imageType">Type of the image.</param> /// <param name="file">The file.</param> - public static void SetImagePath(this IHasImages item, ImageType imageType, FileInfo file) + public static void SetImagePath(this IHasImages item, ImageType imageType, FileSystemInfo file) { item.SetImagePath(imageType, 0, file); } diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs index 1e83c7466..70d5b840f 100644 --- a/MediaBrowser.Controller/Entities/IItemByName.cs +++ b/MediaBrowser.Controller/Entities/IItemByName.cs @@ -1,7 +1,4 @@ -using MediaBrowser.Model.Dto; -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; namespace MediaBrowser.Controller.Entities { @@ -10,37 +7,16 @@ namespace MediaBrowser.Controller.Entities /// </summary> public interface IItemByName { - List<ItemByNameCounts> UserItemCountList { get; set; } + /// <summary> + /// Gets the tagged items. + /// </summary> + /// <param name="inputItems">The input items.</param> + /// <returns>IEnumerable{BaseItem}.</returns> + IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems); } public interface IHasDualAccess : IItemByName { bool IsAccessedByName { get; } } - - public static class ItemByNameExtensions - { - public static ItemByNameCounts GetItemByNameCounts(this IItemByName item, Guid userId) - { - if (userId == Guid.Empty) - { - throw new ArgumentNullException("userId"); - } - - return item.UserItemCountList.FirstOrDefault(i => i.UserId == userId); - } - - public static void SetItemByNameCounts(this IItemByName item, Guid userId, ItemByNameCounts counts) - { - var current = item.UserItemCountList.FirstOrDefault(i => i.UserId == userId); - - if (current != null) - { - item.UserItemCountList.Remove(current); - } - - counts.UserId = userId; - item.UserItemCountList.Add(counts); - } - } } diff --git a/MediaBrowser.Controller/Entities/LinkedChild.cs b/MediaBrowser.Controller/Entities/LinkedChild.cs index cc5f7bf38..1ae04e40f 100644 --- a/MediaBrowser.Controller/Entities/LinkedChild.cs +++ b/MediaBrowser.Controller/Entities/LinkedChild.cs @@ -9,6 +9,10 @@ namespace MediaBrowser.Controller.Entities public string Path { get; set; } public LinkedChildType Type { get; set; } + public string ItemName { get; set; } + public string ItemType { get; set; } + public int? ItemYear { get; set; } + /// <summary> /// Serves as a cache /// </summary> @@ -18,8 +22,8 @@ namespace MediaBrowser.Controller.Entities public enum LinkedChildType { - Manual = 1, - Shortcut = 2 + Manual = 0, + Shortcut = 1 } public class LinkedChildComparer : IEqualityComparer<LinkedChild> @@ -35,7 +39,7 @@ namespace MediaBrowser.Controller.Entities public int GetHashCode(LinkedChild obj) { - return (obj.Path + obj.Type.ToString()).GetHashCode(); + return (obj.Path + obj.Type).GetHashCode(); } } } diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index c1dc81136..1def47391 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -1,7 +1,7 @@ using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Dto; +using System; using System.Collections.Generic; -using System.Runtime.Serialization; +using System.Linq; namespace MediaBrowser.Controller.Entities { @@ -10,19 +10,11 @@ namespace MediaBrowser.Controller.Entities /// </summary> public class Person : BaseItem, IItemByName, IHasLookupInfo<PersonLookupInfo> { - public Person() - { - UserItemCountList = new List<ItemByNameCounts>(); - } - /// <summary> /// Gets or sets the place of birth. /// </summary> /// <value>The place of birth.</value> public string PlaceOfBirth { get; set; } - - [IgnoreDataMember] - public List<ItemByNameCounts> UserItemCountList { get; set; } /// <summary> /// Gets the user data key. @@ -62,6 +54,11 @@ namespace MediaBrowser.Controller.Entities return false; } } + + public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) + { + return inputItems.Where(i => i.People.Any(p => string.Equals(p.Name, Name, StringComparison.OrdinalIgnoreCase))); + } } /// <summary> diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 5c3946f9b..8271a3df2 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -1,7 +1,6 @@ -using System.Runtime.Serialization; -using MediaBrowser.Model.Dto; -using System; +using System; using System.Collections.Generic; +using System.Linq; namespace MediaBrowser.Controller.Entities { @@ -10,11 +9,6 @@ namespace MediaBrowser.Controller.Entities /// </summary> public class Studio : BaseItem, IItemByName { - public Studio() - { - UserItemCountList = new List<ItemByNameCounts>(); - } - /// <summary> /// Gets the user data key. /// </summary> @@ -24,9 +18,6 @@ namespace MediaBrowser.Controller.Entities return "Studio-" + Name; } - [IgnoreDataMember] - public List<ItemByNameCounts> UserItemCountList { get; set; } - /// <summary> /// Returns the folder containing the item. /// If the item is a folder, it returns the folder itself @@ -51,5 +42,10 @@ namespace MediaBrowser.Controller.Entities return false; } } + + public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) + { + return inputItems.Where(i => i.Studios.Contains(Name, StringComparer.OrdinalIgnoreCase)); + } } } diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index 1829e10c7..0290fa39a 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Providers; +using System; using System.Collections.Generic; using System.Linq; @@ -23,7 +24,7 @@ namespace MediaBrowser.Controller.Entities { var hasChanges = base.BeforeMetadataRefresh(); - if (string.Equals("default", Name, System.StringComparison.OrdinalIgnoreCase)) + if (string.Equals("default", Name, StringComparison.OrdinalIgnoreCase)) { Name = "Media Folders"; hasChanges = true; diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index c6ca028ae..8deb930e8 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -1,7 +1,6 @@ -using System.Runtime.Serialization; -using MediaBrowser.Model.Dto; -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; namespace MediaBrowser.Controller.Entities { @@ -10,14 +9,6 @@ namespace MediaBrowser.Controller.Entities /// </summary> public class Year : BaseItem, IItemByName { - public Year() - { - UserItemCountList = new List<ItemByNameCounts>(); - } - - [IgnoreDataMember] - public List<ItemByNameCounts> UserItemCountList { get; set; } - /// <summary> /// Gets the user data key. /// </summary> @@ -51,5 +42,19 @@ namespace MediaBrowser.Controller.Entities return false; } } + + public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) + { + int year; + + var usCulture = new CultureInfo("en-US"); + + if (!int.TryParse(Name, NumberStyles.Integer, usCulture, out year)) + { + return inputItems; + } + + return inputItems.Where(i => i.ProductionYear.HasValue && i.ProductionYear.Value == year); + } } } |
