浏览代码

Merge branch 'master' into websocket

Mark Monteiro 5 年之前
父节点
当前提交
2e09311a93
共有 100 个文件被更改,包括 6520 次插入7947 次删除
  1. 7 10
      .editorconfig
  2. 2 0
      DvdLib/BigEndianBinaryReader.cs
  3. 1 0
      DvdLib/DvdLib.csproj
  4. 2 0
      DvdLib/Ifo/Cell.cs
  5. 2 0
      DvdLib/Ifo/CellPlaybackInfo.cs
  6. 2 0
      DvdLib/Ifo/CellPositionInfo.cs
  7. 2 0
      DvdLib/Ifo/Chapter.cs
  8. 2 0
      DvdLib/Ifo/Dvd.cs
  9. 2 0
      DvdLib/Ifo/DvdTime.cs
  10. 2 0
      DvdLib/Ifo/Program.cs
  11. 2 0
      DvdLib/Ifo/ProgramChain.cs
  12. 2 0
      DvdLib/Ifo/Title.cs
  13. 2 0
      DvdLib/Ifo/UserOperation.cs
  14. 3 3
      Emby.Naming/Video/VideoResolver.cs
  15. 29 40
      Emby.Server.Implementations/ApplicationHost.cs
  16. 4 4
      Emby.Server.Implementations/Browser/BrowserLauncher.cs
  17. 0 1
      Emby.Server.Implementations/ConfigurationOptions.cs
  18. 10 0
      Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
  19. 2 2
      Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
  20. 5 2
      Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
  21. 2 2
      Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
  22. 3 3
      Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
  23. 25 0
      Emby.Server.Implementations/Library/UserManager.cs
  24. 1 1
      Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
  25. 1 1
      Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
  26. 2 2
      Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
  27. 1 1
      Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
  28. 1 1
      Emby.Server.Implementations/Localization/Core/af.json
  29. 3 1
      Emby.Server.Implementations/Localization/Core/bn.json
  30. 1 1
      Emby.Server.Implementations/Localization/Core/es-MX.json
  31. 1 1
      Emby.Server.Implementations/Localization/Core/es.json
  32. 19 1
      Emby.Server.Implementations/Localization/Core/fr-CA.json
  33. 57 35
      Emby.Server.Implementations/Localization/Core/gsw.json
  34. 9 1
      Emby.Server.Implementations/Localization/Core/he.json
  35. 10 2
      Emby.Server.Implementations/Localization/Core/hr.json
  36. 1 1
      Emby.Server.Implementations/Localization/Core/it.json
  37. 8 1
      Emby.Server.Implementations/Localization/Core/mk.json
  38. 3 3
      Emby.Server.Implementations/Localization/Core/nl.json
  39. 22 1
      Emby.Server.Implementations/Localization/Core/sl-SI.json
  40. 36 0
      Emby.Server.Implementations/Localization/Core/uk.json
  41. 5 2
      Emby.Server.Implementations/Localization/Core/zh-HK.json
  42. 7 1
      Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs
  43. 0 1140
      Jellyfin.Data/DbContexts/Jellyfin.cs
  44. 179 192
      Jellyfin.Data/Entities/Artwork.cs
  45. 49 64
      Jellyfin.Data/Entities/Book.cs
  46. 94 110
      Jellyfin.Data/Entities/BookMetadata.cs
  47. 223 234
      Jellyfin.Data/Entities/Chapter.cs
  48. 97 108
      Jellyfin.Data/Entities/Collection.cs
  49. 133 141
      Jellyfin.Data/Entities/CollectionItem.cs
  50. 126 136
      Jellyfin.Data/Entities/Company.cs
  51. 199 217
      Jellyfin.Data/Entities/CompanyMetadata.cs
  52. 49 65
      Jellyfin.Data/Entities/CustomItem.cs
  53. 50 69
      Jellyfin.Data/Entities/CustomItemMetadata.cs
  54. 98 115
      Jellyfin.Data/Entities/Episode.cs
  55. 164 182
      Jellyfin.Data/Entities/EpisodeMetadata.cs
  56. 137 148
      Jellyfin.Data/Entities/Genre.cs
  57. 100 106
      Jellyfin.Data/Entities/Group.cs
  58. 132 143
      Jellyfin.Data/Entities/Library.cs
  59. 156 166
      Jellyfin.Data/Entities/LibraryItem.cs
  60. 178 188
      Jellyfin.Data/Entities/LibraryRoot.cs
  61. 181 190
      Jellyfin.Data/Entities/MediaFile.cs
  62. 134 145
      Jellyfin.Data/Entities/MediaFileStream.cs
  63. 347 352
      Jellyfin.Data/Entities/Metadata.cs
  64. 132 143
      Jellyfin.Data/Entities/MetadataProvider.cs
  65. 167 177
      Jellyfin.Data/Entities/MetadataProviderId.cs
  66. 49 64
      Jellyfin.Data/Entities/Movie.cs
  67. 204 220
      Jellyfin.Data/Entities/MovieMetadata.cs
  68. 49 65
      Jellyfin.Data/Entities/MusicAlbum.cs
  69. 169 184
      Jellyfin.Data/Entities/MusicAlbumMetadata.cs
  70. 132 140
      Jellyfin.Data/Entities/Permission.cs
  71. 0 40
      Jellyfin.Data/Entities/PermissionKind.cs
  72. 256 266
      Jellyfin.Data/Entities/Person.cs
  73. 188 194
      Jellyfin.Data/Entities/PersonRole.cs
  74. 49 65
      Jellyfin.Data/Entities/Photo.cs
  75. 50 68
      Jellyfin.Data/Entities/PhotoMetadata.cs
  76. 99 109
      Jellyfin.Data/Entities/Preference.cs
  77. 0 27
      Jellyfin.Data/Entities/PreferenceKind.cs
  78. 115 125
      Jellyfin.Data/Entities/ProviderMapping.cs
  79. 173 183
      Jellyfin.Data/Entities/Rating.cs
  80. 215 226
      Jellyfin.Data/Entities/RatingSource.cs
  81. 175 184
      Jellyfin.Data/Entities/Release.cs
  82. 98 114
      Jellyfin.Data/Entities/Season.cs
  83. 94 111
      Jellyfin.Data/Entities/SeasonMetadata.cs
  84. 150 166
      Jellyfin.Data/Entities/Series.cs
  85. 204 220
      Jellyfin.Data/Entities/SeriesMetadata.cs
  86. 98 113
      Jellyfin.Data/Entities/Track.cs
  87. 50 68
      Jellyfin.Data/Entities/TrackMetadata.cs
  88. 226 233
      Jellyfin.Data/Entities/User.cs
  89. 8 22
      Jellyfin.Data/Enums/ArtKind.cs
  90. 8 22
      Jellyfin.Data/Enums/MediaFileKind.cs
  91. 26 0
      Jellyfin.Data/Enums/PermissionKind.cs
  92. 15 29
      Jellyfin.Data/Enums/PersonRoleType.cs
  93. 13 0
      Jellyfin.Data/Enums/PreferenceKind.cs
  94. 10 24
      Jellyfin.Data/Enums/Weekday.cs
  95. 9 0
      Jellyfin.Data/ISavingChanges.cs
  96. 0 0
      Jellyfin.Data/Structs/.gitkeep
  97. 34 0
      Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj
  98. 115 0
      Jellyfin.Server.Implementations/JellyfinDb.cs
  99. 1 3
      Jellyfin.Server/Migrations/IMigrationRoutine.cs
  100. 12 7
      Jellyfin.Server/Migrations/MigrationRunner.cs

+ 7 - 10
.editorconfig

@@ -13,7 +13,7 @@ charset = utf-8
 trim_trailing_whitespace = true
 insert_final_newline = true
 end_of_line = lf
-max_line_length = null
+max_line_length = off
 
 # YAML indentation
 [*.{yml,yaml}]
@@ -22,6 +22,7 @@ indent_size = 2
 # XML indentation
 [*.{csproj,xml}]
 indent_size = 2
+
 ###############################
 # .NET Coding Conventions     #
 ###############################
@@ -51,11 +52,12 @@ dotnet_style_explicit_tuple_names = true:suggestion
 dotnet_style_null_propagation = true:suggestion
 dotnet_style_coalesce_expression = true:suggestion
 dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
-dotnet_prefer_inferred_tuple_names = true:suggestion
-dotnet_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
 dotnet_style_prefer_auto_properties = true:silent
 dotnet_style_prefer_conditional_expression_over_assignment = true:silent
 dotnet_style_prefer_conditional_expression_over_return = true:silent
+
 ###############################
 # Naming Conventions          #
 ###############################
@@ -67,7 +69,7 @@ dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non
 dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style
 
 dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field
-dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected internal, private protected
+dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected
 dotnet_naming_symbols.non_private_static_fields.required_modifiers = static
 
 dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case
@@ -159,6 +161,7 @@ csharp_style_deconstructed_variable_declaration = true:suggestion
 csharp_prefer_simple_default_expression = true:suggestion
 csharp_style_pattern_local_over_anonymous_function = true:suggestion
 csharp_style_inlined_variable_declaration = true:suggestion
+
 ###############################
 # C# Formatting Rules         #
 ###############################
@@ -189,9 +192,3 @@ csharp_space_between_method_call_empty_parameter_list_parentheses = false
 # Wrapping preferences
 csharp_preserve_single_line_statements = true
 csharp_preserve_single_line_blocks = true
-###############################
-# VB Coding Conventions       #
-###############################
-[*.vb]
-# Modifier preferences
-visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion

+ 2 - 0
DvdLib/BigEndianBinaryReader.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System.Buffers.Binary;
 using System.IO;
 

+ 1 - 0
DvdLib/DvdLib.csproj

@@ -13,6 +13,7 @@
     <TargetFramework>netstandard2.1</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
   </PropertyGroup>
 
 </Project>

+ 2 - 0
DvdLib/Ifo/Cell.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System.IO;
 
 namespace DvdLib.Ifo

+ 2 - 0
DvdLib/Ifo/CellPlaybackInfo.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System.IO;
 
 namespace DvdLib.Ifo

+ 2 - 0
DvdLib/Ifo/CellPositionInfo.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System.IO;
 
 namespace DvdLib.Ifo

+ 2 - 0
DvdLib/Ifo/Chapter.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 namespace DvdLib.Ifo
 {
     public class Chapter

+ 2 - 0
DvdLib/Ifo/Dvd.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System.Collections.Generic;
 using System.IO;

+ 2 - 0
DvdLib/Ifo/DvdTime.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 
 namespace DvdLib.Ifo

+ 2 - 0
DvdLib/Ifo/Program.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System.Collections.Generic;
 
 namespace DvdLib.Ifo

+ 2 - 0
DvdLib/Ifo/ProgramChain.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;

+ 2 - 0
DvdLib/Ifo/Title.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System.Collections.Generic;
 using System.IO;
 

+ 2 - 0
DvdLib/Ifo/UserOperation.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 
 namespace DvdLib.Ifo

+ 3 - 3
Emby.Naming/Video/VideoResolver.cs

@@ -89,14 +89,14 @@ namespace Emby.Naming.Video
             if (parseName)
             {
                 var cleanDateTimeResult = CleanDateTime(name);
+                name = cleanDateTimeResult.Name;
+                year = cleanDateTimeResult.Year;
 
                 if (extraResult.ExtraType == null
-                    && TryCleanString(cleanDateTimeResult.Name, out ReadOnlySpan<char> newName))
+                    && TryCleanString(name, out ReadOnlySpan<char> newName))
                 {
                     name = newName.ToString();
                 }
-
-                year = cleanDateTimeResult.Year;
             }
 
             return new VideoFileInfo

+ 29 - 40
Emby.Server.Implementations/ApplicationHost.cs

@@ -519,13 +519,6 @@ namespace Emby.Server.Implementations
 
             serviceCollection.AddSingleton<IJsonSerializer, JsonSerializer>();
 
-            // TODO: Remove support for injecting ILogger completely
-            serviceCollection.AddSingleton((provider) =>
-            {
-                Logger.LogWarning("Injecting ILogger directly is deprecated and should be replaced with ILogger<T>");
-                return Logger;
-            });
-
             serviceCollection.AddSingleton(_fileSystemManager);
             serviceCollection.AddSingleton<TvdbClientManager>();
 
@@ -1122,9 +1115,6 @@ namespace Emby.Server.Implementations
                 ItemsByNamePath = ApplicationPaths.InternalMetadataPath,
                 InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
                 CachePath = ApplicationPaths.CachePath,
-                HttpServerPortNumber = HttpPort,
-                SupportsHttps = SupportsHttps,
-                HttpsPortNumber = HttpsPort,
                 OperatingSystem = OperatingSystem.Id.ToString(),
                 OperatingSystemDisplayName = OperatingSystem.Name,
                 CanSelfRestart = CanSelfRestart,
@@ -1160,23 +1150,22 @@ namespace Emby.Server.Implementations
             };
         }
 
-        public bool EnableHttps => SupportsHttps && ServerConfigurationManager.Configuration.EnableHttps;
-
-        public bool SupportsHttps => Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy;
+        /// <inheritdoc/>
+        public bool ListenWithHttps => Certificate != null && ServerConfigurationManager.Configuration.EnableHttps;
 
-        public async Task<string> GetLocalApiUrl(CancellationToken cancellationToken, bool forceHttp = false)
+        /// <inheritdoc/>
+        public async Task<string> GetLocalApiUrl(CancellationToken cancellationToken)
         {
             try
             {
                 // Return the first matched address, if found, or the first known local address
                 var addresses = await GetLocalIpAddressesInternal(false, 1, cancellationToken).ConfigureAwait(false);
-
-                foreach (var address in addresses)
+                if (addresses.Count == 0)
                 {
-                    return GetLocalApiUrl(address, forceHttp);
+                    return null;
                 }
 
-                return null;
+                return GetLocalApiUrl(addresses.First());
             }
             catch (Exception ex)
             {
@@ -1203,7 +1192,7 @@ namespace Emby.Server.Implementations
         }
 
         /// <inheritdoc />
-        public string GetLocalApiUrl(IPAddress ipAddress, bool forceHttp = false)
+        public string GetLocalApiUrl(IPAddress ipAddress)
         {
             if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
             {
@@ -1213,29 +1202,30 @@ namespace Emby.Server.Implementations
                 str.CopyTo(span.Slice(1));
                 span[^1] = ']';
 
-                return GetLocalApiUrl(span, forceHttp);
+                return GetLocalApiUrl(span);
             }
 
-            return GetLocalApiUrl(ipAddress.ToString(), forceHttp);
+            return GetLocalApiUrl(ipAddress.ToString());
         }
 
-        /// <inheritdoc />
-        public string GetLocalApiUrl(ReadOnlySpan<char> host, bool forceHttp = false)
+        /// <inheritdoc/>
+        public string GetLoopbackHttpApiUrl()
         {
-            var url = new StringBuilder(64);
-            bool useHttps = EnableHttps && !forceHttp;
-            url.Append(useHttps ? "https://" : "http://")
-                .Append(host)
-                .Append(':')
-                .Append(useHttps ? HttpsPort : HttpPort);
-
-            string baseUrl = ServerConfigurationManager.Configuration.BaseUrl;
-            if (baseUrl.Length != 0)
-            {
-                url.Append(baseUrl);
-            }
+            return GetLocalApiUrl("127.0.0.1", Uri.UriSchemeHttp, HttpPort);
+        }
 
-            return url.ToString();
+        /// <inheritdoc/>
+        public string GetLocalApiUrl(ReadOnlySpan<char> host, string scheme = null, int? port = null)
+        {
+            // NOTE: If no BaseUrl is set then UriBuilder appends a trailing slash, but if there is no BaseUrl it does
+            // not. For consistency, always trim the trailing slash.
+            return new UriBuilder
+            {
+                Scheme = scheme ?? (ListenWithHttps ? Uri.UriSchemeHttps : Uri.UriSchemeHttp),
+                Host = host.ToString(),
+                Port = port ?? (ListenWithHttps ? HttpsPort : HttpPort),
+                Path = ServerConfigurationManager.Configuration.BaseUrl
+            }.ToString().TrimEnd('/');
         }
 
         public Task<List<IPAddress>> GetLocalIpAddresses(CancellationToken cancellationToken)
@@ -1269,7 +1259,7 @@ namespace Emby.Server.Implementations
                     }
                 }
 
-                var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false);
+                var valid = await IsLocalIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false);
                 if (valid)
                 {
                     resultList.Add(address);
@@ -1303,7 +1293,7 @@ namespace Emby.Server.Implementations
 
         private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
 
-        private async Task<bool> IsIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken)
+        private async Task<bool> IsLocalIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken)
         {
             if (address.Equals(IPAddress.Loopback)
                 || address.Equals(IPAddress.IPv6Loopback))
@@ -1311,8 +1301,7 @@ namespace Emby.Server.Implementations
                 return true;
             }
 
-            var apiUrl = GetLocalApiUrl(address);
-            apiUrl += "/system/ping";
+            var apiUrl = GetLocalApiUrl(address) + "/system/ping";
 
             if (_validAddressResults.TryGetValue(apiUrl, out var cachedResult))
             {

+ 4 - 4
Emby.Server.Implementations/Browser/BrowserLauncher.cs

@@ -31,18 +31,18 @@ namespace Emby.Server.Implementations.Browser
         /// Opens the specified URL in an external browser window. Any exceptions will be logged, but ignored.
         /// </summary>
         /// <param name="appHost">The application host.</param>
-        /// <param name="url">The URL.</param>
-        private static void TryOpenUrl(IServerApplicationHost appHost, string url)
+        /// <param name="relativeUrl">The URL to open, relative to the server base URL.</param>
+        private static void TryOpenUrl(IServerApplicationHost appHost, string relativeUrl)
         {
             try
             {
                 string baseUrl = appHost.GetLocalApiUrl("localhost");
-                appHost.LaunchUrl(baseUrl + url);
+                appHost.LaunchUrl(baseUrl + relativeUrl);
             }
             catch (Exception ex)
             {
                 var logger = appHost.Resolve<ILogger>();
-                logger?.LogError(ex, "Failed to open browser window with URL {URL}", url);
+                logger?.LogError(ex, "Failed to open browser window with URL {URL}", relativeUrl);
             }
         }
     }

+ 0 - 1
Emby.Server.Implementations/ConfigurationOptions.cs

@@ -1,7 +1,6 @@
 using System.Collections.Generic;
 using Emby.Server.Implementations.HttpServer;
 using Emby.Server.Implementations.Updates;
-using MediaBrowser.Providers.Music;
 using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
 
 namespace Emby.Server.Implementations

+ 10 - 0
Emby.Server.Implementations/Data/SqliteUserDataRepository.cs

@@ -375,5 +375,15 @@ namespace Emby.Server.Implementations.Data
 
             return userData;
         }
+
+        /// <inheritdoc/>
+        /// <remarks>
+        /// There is nothing to dispose here since <see cref="BaseSqliteRepository.WriteLock"/> and
+        /// <see cref="BaseSqliteRepository.WriteConnection"/> are managed by <see cref="SqliteItemRepository"/>.
+        /// See <see cref="Initialize(IUserManager, SemaphoreSlim, SQLiteDatabaseConnection)"/>.
+        /// </remarks>
+        protected override void Dispose(bool dispose)
+        {
+        }
     }
 }

+ 2 - 2
Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs

@@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.EntryPoints
                 .Append(config.PublicHttpsPort).Append(Separator)
                 .Append(_appHost.HttpPort).Append(Separator)
                 .Append(_appHost.HttpsPort).Append(Separator)
-                .Append(_appHost.EnableHttps).Append(Separator)
+                .Append(_appHost.ListenWithHttps).Append(Separator)
                 .Append(config.EnableRemoteAccess).Append(Separator)
                 .ToString();
         }
@@ -158,7 +158,7 @@ namespace Emby.Server.Implementations.EntryPoints
         {
             yield return CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort);
 
-            if (_appHost.EnableHttps)
+            if (_appHost.ListenWithHttps)
             {
                 yield return CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort);
             }

+ 5 - 2
Emby.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -366,11 +366,14 @@ namespace Emby.Server.Implementations.HttpServer
             return true;
         }
 
+        /// <summary>
+        /// Validate a connection from a remote IP address to a URL to see if a redirection to HTTPS is required.
+        /// </summary>
+        /// <returns>True if the request is valid, or false if the request is not valid and an HTTPS redirect is required.</returns>
         private bool ValidateSsl(string remoteIp, string urlString)
         {
             if (_config.Configuration.RequireHttps
-                && _appHost.EnableHttps
-                && !_config.Configuration.IsBehindProxy
+                && _appHost.ListenWithHttps
                 && !urlString.Contains("https://", StringComparison.OrdinalIgnoreCase))
             {
                 // These are hacks, but if these ever occur on ipv6 in the local network they could be incorrectly redirected

+ 2 - 2
Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs

@@ -16,7 +16,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
     /// </summary>
     public class MusicAlbumResolver : ItemResolver<MusicAlbum>
     {
-        private readonly ILogger _logger;
+        private readonly ILogger<MusicAlbumResolver> _logger;
         private readonly IFileSystem _fileSystem;
         private readonly ILibraryManager _libraryManager;
 
@@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
         /// <param name="logger">The logger.</param>
         /// <param name="fileSystem">The file system.</param>
         /// <param name="libraryManager">The library manager.</param>
-        public MusicAlbumResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager)
+        public MusicAlbumResolver(ILogger<MusicAlbumResolver> logger, IFileSystem fileSystem, ILibraryManager libraryManager)
         {
             _logger = logger;
             _fileSystem = fileSystem;

+ 3 - 3
Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs

@@ -15,7 +15,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
     /// </summary>
     public class MusicArtistResolver : ItemResolver<MusicArtist>
     {
-        private readonly ILogger _logger;
+        private readonly ILogger<MusicAlbumResolver> _logger;
         private readonly IFileSystem _fileSystem;
         private readonly ILibraryManager _libraryManager;
         private readonly IServerConfigurationManager _config;
@@ -23,12 +23,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
         /// <summary>
         /// Initializes a new instance of the <see cref="MusicArtistResolver"/> class.
         /// </summary>
-        /// <param name="logger">The logger.</param>
+        /// <param name="logger">The logger for the created <see cref="MusicAlbumResolver"/> instances.</param>
         /// <param name="fileSystem">The file system.</param>
         /// <param name="libraryManager">The library manager.</param>
         /// <param name="config">The configuration manager.</param>
         public MusicArtistResolver(
-            ILogger<MusicArtistResolver> logger,
+            ILogger<MusicAlbumResolver> logger,
             IFileSystem fileSystem,
             ILibraryManager libraryManager,
             IServerConfigurationManager config)

+ 25 - 0
Emby.Server.Implementations/Library/UserManager.cs

@@ -608,6 +608,31 @@ namespace Emby.Server.Implementations.Library
             return dto;
         }
 
+        public PublicUserDto GetPublicUserDto(User user, string remoteEndPoint = null)
+        {
+            if (user == null)
+            {
+                throw new ArgumentNullException(nameof(user));
+            }
+
+            IAuthenticationProvider authenticationProvider = GetAuthenticationProvider(user);
+            bool hasConfiguredPassword = authenticationProvider.HasPassword(user);
+            bool hasConfiguredEasyPassword = !string.IsNullOrEmpty(authenticationProvider.GetEasyPasswordHash(user));
+
+            bool hasPassword = user.Configuration.EnableLocalPassword &&
+                !string.IsNullOrEmpty(remoteEndPoint) &&
+                _networkManager.IsInLocalNetwork(remoteEndPoint) ? hasConfiguredEasyPassword : hasConfiguredPassword;
+
+            PublicUserDto dto = new PublicUserDto
+            {
+                Name = user.Name,
+                HasPassword = hasPassword,
+                HasConfiguredPassword = hasConfiguredPassword,
+            };
+
+            return dto;
+        }
+
         public UserDto GetOfflineUserDto(User user)
         {
             var dto = GetUserDto(user);

+ 1 - 1
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -1059,7 +1059,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
         {
             var stream = new MediaSourceInfo
             {
-                EncoderPath = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
+                EncoderPath = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
                 EncoderProtocol = MediaProtocol.Http,
                 Path = info.Path,
                 Protocol = MediaProtocol.File,

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs

@@ -121,7 +121,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             //OpenedMediaSource.Path = tempFile;
             //OpenedMediaSource.ReadAtNativeFramerate = true;
 
-            MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
+            MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
             MediaSource.Protocol = MediaProtocol.Http;
             //OpenedMediaSource.SupportsDirectPlay = false;
             //OpenedMediaSource.SupportsDirectStream = true;

+ 2 - 2
Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs

@@ -35,7 +35,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
         public M3UTunerHost(
             IServerConfigurationManager config,
             IMediaSourceManager mediaSourceManager,
-            ILogger logger,
+            ILogger<M3UTunerHost> logger,
             IJsonSerializer jsonSerializer,
             IFileSystem fileSystem,
             IHttpClient httpClient,
@@ -83,7 +83,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
             return Task.FromResult(list);
         }
 
-        private static readonly string[] _disallowedSharedStreamExtensions = new string[]
+        private static readonly string[] _disallowedSharedStreamExtensions =
         {
             ".mkv",
             ".mp4",

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs

@@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
             //OpenedMediaSource.Path = tempFile;
             //OpenedMediaSource.ReadAtNativeFramerate = true;
 
-            MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
+            MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
             MediaSource.Protocol = MediaProtocol.Http;
 
             //OpenedMediaSource.Path = TempFilePath;

+ 1 - 1
Emby.Server.Implementations/Localization/Core/af.json

@@ -4,7 +4,7 @@
     "Folders": "Fouers",
     "Favorites": "Gunstelinge",
     "HeaderFavoriteShows": "Gunsteling Vertonings",
-    "ValueSpecialEpisodeName": "Spesiaal - {0}",
+    "ValueSpecialEpisodeName": "Spesiale - {0}",
     "HeaderAlbumArtists": "Album Kunstenaars",
     "Books": "Boeke",
     "HeaderNextUp": "Volgende",

+ 3 - 1
Emby.Server.Implementations/Localization/Core/bn.json

@@ -91,5 +91,7 @@
     "HeaderNextUp": "এরপরে আসছে",
     "HeaderLiveTV": "লাইভ টিভি",
     "HeaderFavoriteSongs": "প্রিয় গানগুলো",
-    "HeaderFavoriteShows": "প্রিয় শোগুলো"
+    "HeaderFavoriteShows": "প্রিয় শোগুলো",
+    "TasksLibraryCategory": "গ্রন্থাগার",
+    "TasksMaintenanceCategory": "রক্ষণাবেক্ষণ"
 }

+ 1 - 1
Emby.Server.Implementations/Localization/Core/es-MX.json

@@ -11,7 +11,7 @@
     "Collections": "Colecciones",
     "DeviceOfflineWithName": "{0} se ha desconectado",
     "DeviceOnlineWithName": "{0} está conectado",
-    "FailedLoginAttemptWithUserName": "Intento fallido de inicio de sesión de {0}",
+    "FailedLoginAttemptWithUserName": "Intento fallido de inicio de sesión desde {0}",
     "Favorites": "Favoritos",
     "Folders": "Carpetas",
     "Genres": "Géneros",

+ 1 - 1
Emby.Server.Implementations/Localization/Core/es.json

@@ -71,7 +71,7 @@
     "ScheduledTaskFailedWithName": "{0} falló",
     "ScheduledTaskStartedWithName": "{0} iniciada",
     "ServerNameNeedsToBeRestarted": "{0} necesita ser reiniciado",
-    "Shows": "Series",
+    "Shows": "Mostrar",
     "Songs": "Canciones",
     "StartupEmbyServerIsLoading": "Jellyfin Server se está cargando. Vuelve a intentarlo en breve.",
     "SubtitleDownloadFailureForItem": "Error al descargar subtítulos para {0}",

+ 19 - 1
Emby.Server.Implementations/Localization/Core/fr-CA.json

@@ -94,5 +94,23 @@
     "ValueSpecialEpisodeName": "Spécial - {0}",
     "VersionNumber": "Version {0}",
     "TasksLibraryCategory": "Bibliothèque",
-    "TasksMaintenanceCategory": "Entretien"
+    "TasksMaintenanceCategory": "Entretien",
+    "TaskDownloadMissingSubtitlesDescription": "Recherche l'internet pour des sous-titres manquants à base de métadonnées configurées.",
+    "TaskDownloadMissingSubtitles": "Télécharger des sous-titres manquants",
+    "TaskRefreshChannelsDescription": "Rafraîchit des informations des chaines d'internet.",
+    "TaskRefreshChannels": "Rafraîchir des chaines",
+    "TaskCleanTranscodeDescription": "Retirer des fichiers de transcodage de plus qu'un jour.",
+    "TaskCleanTranscode": "Nettoyer le directoire de transcodage",
+    "TaskUpdatePluginsDescription": "Télécharger et installer des mises à jours des plugins qui sont configurés m.à.j. automisés.",
+    "TaskUpdatePlugins": "Mise à jour des plugins",
+    "TaskRefreshPeopleDescription": "Met à jour les métadonnées pour les acteurs et réalisateurs dans votre bibliothèque.",
+    "TaskRefreshPeople": "Rafraîchir les acteurs",
+    "TaskCleanLogsDescription": "Retire les données qui ont plus que {0} jours.",
+    "TaskCleanLogs": "Nettoyer les données de directoire",
+    "TaskRefreshLibraryDescription": "Analyse votre bibliothèque média pour des nouveaux fichiers et rafraîchit les métadonnées.",
+    "TaskRefreshChapterImages": "Extraire des images du chapitre",
+    "TaskRefreshChapterImagesDescription": "Créer des vignettes pour des vidéos qui ont des chapitres",
+    "TaskRefreshLibrary": "Analyser la bibliothèque de média",
+    "TaskCleanCache": "Nettoyer le cache de directoire",
+    "TasksApplicationCategory": "Application"
 }

+ 57 - 35
Emby.Server.Implementations/Localization/Core/gsw.json

@@ -1,41 +1,41 @@
 {
-    "Albums": "Albom",
-    "AppDeviceValues": "App: {0}, Grät: {1}",
-    "Application": "Aawändig",
-    "Artists": "Könstler",
-    "AuthenticationSucceededWithUserName": "{0} het sech aagmäudet",
-    "Books": "Büecher",
-    "CameraImageUploadedFrom": "Es nöis Foti esch ufeglade worde vo {0}",
-    "Channels": "Kanäu",
-    "ChapterNameValue": "Kapitu {0}",
-    "Collections": "Sammlige",
-    "DeviceOfflineWithName": "{0} esch offline gange",
-    "DeviceOnlineWithName": "{0} esch online cho",
-    "FailedLoginAttemptWithUserName": "Fäugschlagne Aamäudeversuech vo {0}",
-    "Favorites": "Favorite",
+    "Albums": "Alben",
+    "AppDeviceValues": "App: {0}, Gerät: {1}",
+    "Application": "Anwendung",
+    "Artists": "Künstler",
+    "AuthenticationSucceededWithUserName": "{0} hat sich angemeldet",
+    "Books": "Bücher",
+    "CameraImageUploadedFrom": "Ein neues Foto wurde von {0} hochgeladen",
+    "Channels": "Kanäle",
+    "ChapterNameValue": "Kapitel {0}",
+    "Collections": "Sammlungen",
+    "DeviceOfflineWithName": "{0} wurde getrennt",
+    "DeviceOnlineWithName": "{0} ist verbunden",
+    "FailedLoginAttemptWithUserName": "Fehlgeschlagener Anmeldeversuch von {0}",
+    "Favorites": "Favoriten",
     "Folders": "Ordner",
     "Genres": "Genres",
-    "HeaderAlbumArtists": "Albom-Könstler",
+    "HeaderAlbumArtists": "Album-Künstler",
     "HeaderCameraUploads": "Kamera-Uploads",
-    "HeaderContinueWatching": "Wiiterluege",
-    "HeaderFavoriteAlbums": "Lieblingsalbe",
-    "HeaderFavoriteArtists": "Lieblings-Interprete",
-    "HeaderFavoriteEpisodes": "Lieblingsepisode",
-    "HeaderFavoriteShows": "Lieblingsserie",
+    "HeaderContinueWatching": "weiter schauen",
+    "HeaderFavoriteAlbums": "Lieblingsalben",
+    "HeaderFavoriteArtists": "Lieblings-Künstler",
+    "HeaderFavoriteEpisodes": "Lieblingsepisoden",
+    "HeaderFavoriteShows": "Lieblingsserien",
     "HeaderFavoriteSongs": "Lieblingslieder",
-    "HeaderLiveTV": "Live-Färnseh",
-    "HeaderNextUp": "Als nächts",
-    "HeaderRecordingGroups": "Ufnahmegruppe",
-    "HomeVideos": "Heimfilmli",
-    "Inherit": "Hinzuefüege",
-    "ItemAddedWithName": "{0} esch de Bibliothek dezuegfüegt worde",
-    "ItemRemovedWithName": "{0} esch vo de Bibliothek entfärnt worde",
-    "LabelIpAddressValue": "IP-Adrässe: {0}",
-    "LabelRunningTimeValue": "Loufziit: {0}",
-    "Latest": "Nöischti",
-    "MessageApplicationUpdated": "Jellyfin Server esch aktualisiert worde",
-    "MessageApplicationUpdatedTo": "Jellyfin Server esch of Version {0} aktualisiert worde",
-    "MessageNamedServerConfigurationUpdatedWithValue": "De Serveriistöuigsberiich {0} esch aktualisiert worde",
+    "HeaderLiveTV": "Live-Fernseh",
+    "HeaderNextUp": "Als Nächstes",
+    "HeaderRecordingGroups": "Aufnahme-Gruppen",
+    "HomeVideos": "Heimvideos",
+    "Inherit": "Vererben",
+    "ItemAddedWithName": "{0} wurde der Bibliothek hinzugefügt",
+    "ItemRemovedWithName": "{0} wurde aus der Bibliothek entfernt",
+    "LabelIpAddressValue": "IP-Adresse: {0}",
+    "LabelRunningTimeValue": "Laufzeit: {0}",
+    "Latest": "Neueste",
+    "MessageApplicationUpdated": "Jellyfin-Server wurde aktualisiert",
+    "MessageApplicationUpdatedTo": "Jellyfin-Server wurde auf Version {0} aktualisiert",
+    "MessageNamedServerConfigurationUpdatedWithValue": "Der Server-Einstellungsbereich {0} wurde aktualisiert",
     "MessageServerConfigurationUpdated": "Serveriistöuige send aktualisiert worde",
     "MixedContent": "Gmeschti Inhäut",
     "Movies": "Film",
@@ -50,7 +50,7 @@
     "NotificationOptionAudioPlayback": "Audiowedergab gstartet",
     "NotificationOptionAudioPlaybackStopped": "Audiwedergab gstoppt",
     "NotificationOptionCameraImageUploaded": "Foti ueglade",
-    "NotificationOptionInstallationFailed": "Installationsfäuer",
+    "NotificationOptionInstallationFailed": "Installationsfehler",
     "NotificationOptionNewLibraryContent": "Nöie Inhaut hinzuegfüegt",
     "NotificationOptionPluginError": "Plugin-Fäuer",
     "NotificationOptionPluginInstalled": "Plugin installiert",
@@ -92,5 +92,27 @@
     "UserStoppedPlayingItemWithValues": "{0} het d'Wedergab vo {1} of {2} gstoppt",
     "ValueHasBeenAddedToLibrary": "{0} esch dinnere Biblithek hinzuegfüegt worde",
     "ValueSpecialEpisodeName": "Extra - {0}",
-    "VersionNumber": "Version {0}"
+    "VersionNumber": "Version {0}",
+    "TaskCleanLogs": "Lösche Log Pfad",
+    "TaskRefreshLibraryDescription": "Scanne alle Bibliotheken für hinzugefügte Datein und erneuere Metadaten.",
+    "TaskRefreshLibrary": "Scanne alle Bibliotheken",
+    "TaskRefreshChapterImagesDescription": "Kreiert Vorschaubilder für Videos welche Kapitel haben.",
+    "TaskRefreshChapterImages": "Extrahiere Kapitel-Bilder",
+    "TaskCleanCacheDescription": "Löscht Zwischenspeicherdatein die nicht länger von System gebraucht werden.",
+    "TaskCleanCache": "Leere Cache Pfad",
+    "TasksChannelsCategory": "Internet Kanäle",
+    "TasksApplicationCategory": "Applikation",
+    "TasksLibraryCategory": "Bibliothek",
+    "TasksMaintenanceCategory": "Verwaltung",
+    "TaskDownloadMissingSubtitlesDescription": "Durchsucht das Internet nach fehlenden Untertiteln, basierend auf den Metadaten Einstellungen.",
+    "TaskDownloadMissingSubtitles": "Lade fehlende Untertitel herunter",
+    "TaskRefreshChannelsDescription": "Aktualisiert Internet Kanal Informationen.",
+    "TaskRefreshChannels": "Aktualisiere Kanäle",
+    "TaskCleanTranscodeDescription": "Löscht Transkodierdateien welche älter als ein Tag sind.",
+    "TaskCleanTranscode": "Räume Transcodier Verzeichnis auf",
+    "TaskUpdatePluginsDescription": "Lädt Aktualisierungen für Erweiterungen herunter und installiert diese, für welche automatische Aktualisierungen konfiguriert sind.",
+    "TaskUpdatePlugins": "Aktualisiere Erweiterungen",
+    "TaskRefreshPeopleDescription": "Aktualisiert Metadaten für Schausteller und Regisseure in deiner Bibliothek.",
+    "TaskRefreshPeople": "Aktualisiere Schauspieler",
+    "TaskCleanLogsDescription": "Löscht Log Dateien die älter als {0} Tage sind."
 }

+ 9 - 1
Emby.Server.Implementations/Localization/Core/he.json

@@ -99,5 +99,13 @@
     "TaskCleanCache": "נקה תיקיית מטמון",
     "TasksApplicationCategory": "יישום",
     "TasksLibraryCategory": "ספרייה",
-    "TasksMaintenanceCategory": "תחזוקה"
+    "TasksMaintenanceCategory": "תחזוקה",
+    "TaskUpdatePlugins": "עדכן תוספים",
+    "TaskRefreshPeopleDescription": "מעדכן מטא נתונים עבור שחקנים ובמאים בספריית המדיה שלך.",
+    "TaskRefreshPeople": "רענן אנשים",
+    "TaskCleanLogsDescription": "מוחק קבצי יומן בני יותר מ- {0} ימים.",
+    "TaskCleanLogs": "נקה תיקיית יומן",
+    "TaskRefreshLibraryDescription": "סורק את ספריית המדיה שלך אחר קבצים חדשים ומרענן מטא נתונים.",
+    "TaskRefreshChapterImagesDescription": "יוצר תמונות ממוזערות לסרטונים שיש להם פרקים.",
+    "TasksChannelsCategory": "ערוצי אינטרנט"
 }

+ 10 - 2
Emby.Server.Implementations/Localization/Core/hr.json

@@ -30,7 +30,7 @@
     "Inherit": "Naslijedi",
     "ItemAddedWithName": "{0} je dodano u biblioteku",
     "ItemRemovedWithName": "{0} je uklonjen iz biblioteke",
-    "LabelIpAddressValue": "Ip adresa: {0}",
+    "LabelIpAddressValue": "IP adresa: {0}",
     "LabelRunningTimeValue": "Vrijeme rada: {0}",
     "Latest": "Najnovije",
     "MessageApplicationUpdated": "Jellyfin Server je ažuriran",
@@ -92,5 +92,13 @@
     "UserStoppedPlayingItemWithValues": "{0} je zaustavio {1}",
     "ValueHasBeenAddedToLibrary": "{0} has been added to your media library",
     "ValueSpecialEpisodeName": "Specijal - {0}",
-    "VersionNumber": "Verzija {0}"
+    "VersionNumber": "Verzija {0}",
+    "TaskRefreshLibraryDescription": "Skenira vašu medijsku knjižnicu sa novim datotekama i osvježuje metapodatke.",
+    "TaskRefreshLibrary": "Skeniraj medijsku knjižnicu",
+    "TaskRefreshChapterImagesDescription": "Stvara sličice za videozapise koji imaju poglavlja.",
+    "TaskRefreshChapterImages": "Raspakiraj slike poglavlja",
+    "TaskCleanCacheDescription": "Briše priručne datoteke nepotrebne za sistem.",
+    "TaskCleanCache": "Očisti priručnu memoriju",
+    "TasksApplicationCategory": "Aplikacija",
+    "TasksMaintenanceCategory": "Održavanje"
 }

+ 1 - 1
Emby.Server.Implementations/Localization/Core/it.json

@@ -5,7 +5,7 @@
     "Artists": "Artisti",
     "AuthenticationSucceededWithUserName": "{0} autenticato con successo",
     "Books": "Libri",
-    "CameraImageUploadedFrom": "È stata caricata una nuova immagine della fotocamera dal device {0}",
+    "CameraImageUploadedFrom": "È stata caricata una nuova fotografia da {0}",
     "Channels": "Canali",
     "ChapterNameValue": "Capitolo {0}",
     "Collections": "Collezioni",

+ 8 - 1
Emby.Server.Implementations/Localization/Core/mk.json

@@ -91,5 +91,12 @@
     "Songs": "Песни",
     "Shows": "Серии",
     "ServerNameNeedsToBeRestarted": "{0} треба да се рестартира",
-    "ScheduledTaskStartedWithName": "{0} започна"
+    "ScheduledTaskStartedWithName": "{0} започна",
+    "TaskRefreshChapterImages": "Извези Слики од Поглавје",
+    "TaskCleanCacheDescription": "Ги брише кешираните фајлови што не се повеќе потребни од системот.",
+    "TaskCleanCache": "Исчисти Го Кешот",
+    "TasksChannelsCategory": "Интернет Канали",
+    "TasksApplicationCategory": "Апликација",
+    "TasksLibraryCategory": "Библиотека",
+    "TasksMaintenanceCategory": "Одржување"
 }

+ 3 - 3
Emby.Server.Implementations/Localization/Core/nl.json

@@ -5,7 +5,7 @@
     "Artists": "Artiesten",
     "AuthenticationSucceededWithUserName": "{0} is succesvol geverifieerd",
     "Books": "Boeken",
-    "CameraImageUploadedFrom": "Er is een nieuwe afbeelding toegevoegd via {0}",
+    "CameraImageUploadedFrom": "Er is een nieuwe camera afbeelding toegevoegd via {0}",
     "Channels": "Kanalen",
     "ChapterNameValue": "Hoofdstuk {0}",
     "Collections": "Verzamelingen",
@@ -26,7 +26,7 @@
     "HeaderLiveTV": "Live TV",
     "HeaderNextUp": "Volgende",
     "HeaderRecordingGroups": "Opnamegroepen",
-    "HomeVideos": "Start video's",
+    "HomeVideos": "Home video's",
     "Inherit": "Overerven",
     "ItemAddedWithName": "{0} is toegevoegd aan de bibliotheek",
     "ItemRemovedWithName": "{0} is verwijderd uit de bibliotheek",
@@ -50,7 +50,7 @@
     "NotificationOptionAudioPlayback": "Muziek gestart",
     "NotificationOptionAudioPlaybackStopped": "Muziek gestopt",
     "NotificationOptionCameraImageUploaded": "Camera-afbeelding geüpload",
-    "NotificationOptionInstallationFailed": "Installatie mislukking",
+    "NotificationOptionInstallationFailed": "Installatie mislukt",
     "NotificationOptionNewLibraryContent": "Nieuwe content toegevoegd",
     "NotificationOptionPluginError": "Plug-in fout",
     "NotificationOptionPluginInstalled": "Plug-in geïnstalleerd",

+ 22 - 1
Emby.Server.Implementations/Localization/Core/sl-SI.json

@@ -92,5 +92,26 @@
     "UserStoppedPlayingItemWithValues": "{0} je nehal predvajati {1} na {2}",
     "ValueHasBeenAddedToLibrary": "{0} je bil dodan vaši knjižnici",
     "ValueSpecialEpisodeName": "Poseben - {0}",
-    "VersionNumber": "Različica {0}"
+    "VersionNumber": "Različica {0}",
+    "TaskDownloadMissingSubtitles": "Prenesi manjkajoče podnapise",
+    "TaskRefreshChannelsDescription": "Osveži podatke spletnih kanalov.",
+    "TaskRefreshChannels": "Osveži kanale",
+    "TaskCleanTranscodeDescription": "Izbriše več kot dan stare datoteke prekodiranja.",
+    "TaskCleanTranscode": "Počisti mapo prekodiranja",
+    "TaskUpdatePluginsDescription": "Prenese in namesti posodobitve za dodatke, ki imajo omogočene samodejne posodobitve.",
+    "TaskUpdatePlugins": "Posodobi dodatke",
+    "TaskRefreshPeopleDescription": "Osveži metapodatke za igralce in režiserje v vaši knjižnici.",
+    "TaskRefreshPeople": "Osveži osebe",
+    "TaskCleanLogsDescription": "Izbriše dnevniške datoteke starejše od {0} dni.",
+    "TaskCleanLogs": "Počisti mapo dnevnika",
+    "TaskRefreshLibraryDescription": "Preišče vašo knjižnico za nove datoteke in osveži metapodatke.",
+    "TaskRefreshLibrary": "Preišči knjižnico predstavnosti",
+    "TaskRefreshChapterImagesDescription": "Ustvari sličice za poglavja videoposnetkov.",
+    "TaskRefreshChapterImages": "Izvleči slike poglavij",
+    "TaskCleanCacheDescription": "Izbriše predpomnjene datoteke, ki niso več potrebne.",
+    "TaskCleanCache": "Počisti mapo predpomnilnika",
+    "TasksChannelsCategory": "Spletni kanali",
+    "TasksApplicationCategory": "Aplikacija",
+    "TasksLibraryCategory": "Knjižnica",
+    "TasksMaintenanceCategory": "Vzdrževanje"
 }

+ 36 - 0
Emby.Server.Implementations/Localization/Core/uk.json

@@ -0,0 +1,36 @@
+{
+    "MusicVideos": "Музичні відео",
+    "Music": "Музика",
+    "Movies": "Фільми",
+    "MessageApplicationUpdatedTo": "Jellyfin Server був оновлений до версії {0}",
+    "MessageApplicationUpdated": "Jellyfin Server був оновлений",
+    "Latest": "Останні",
+    "LabelIpAddressValue": "IP-адреси: {0}",
+    "ItemRemovedWithName": "{0} видалено з бібліотеки",
+    "ItemAddedWithName": "{0} додано до бібліотеки",
+    "HeaderNextUp": "Наступний",
+    "HeaderLiveTV": "Ефірне ТБ",
+    "HeaderFavoriteSongs": "Улюблені пісні",
+    "HeaderFavoriteShows": "Улюблені шоу",
+    "HeaderFavoriteEpisodes": "Улюблені серії",
+    "HeaderFavoriteArtists": "Улюблені виконавці",
+    "HeaderFavoriteAlbums": "Улюблені альбоми",
+    "HeaderContinueWatching": "Продовжити перегляд",
+    "HeaderCameraUploads": "Завантажено з камери",
+    "HeaderAlbumArtists": "Виконавці альбомів",
+    "Genres": "Жанри",
+    "Folders": "Директорії",
+    "Favorites": "Улюблені",
+    "DeviceOnlineWithName": "{0} під'єднано",
+    "DeviceOfflineWithName": "{0} від'єднано",
+    "Collections": "Колекції",
+    "ChapterNameValue": "Глава {0}",
+    "Channels": "Канали",
+    "CameraImageUploadedFrom": "Нова фотографія завантажена з {0}",
+    "Books": "Книги",
+    "AuthenticationSucceededWithUserName": "{0} успішно авторизовані",
+    "Artists": "Виконавці",
+    "Application": "Додаток",
+    "AppDeviceValues": "Додаток: {0}, Пристрій: {1}",
+    "Albums": "Альбоми"
+}

+ 5 - 2
Emby.Server.Implementations/Localization/Core/zh-HK.json

@@ -1,6 +1,6 @@
 {
     "Albums": "專輯",
-    "AppDeviceValues": "軟: {0}, 設備: {1}",
+    "AppDeviceValues": "軟: {0}, 設備: {1}",
     "Application": "應用程式",
     "Artists": "藝人",
     "AuthenticationSucceededWithUserName": "{0} 授權成功",
@@ -92,5 +92,8 @@
     "UserStoppedPlayingItemWithValues": "{0} 已在 {2} 上停止播放 {1}",
     "ValueHasBeenAddedToLibrary": "{0} 已添加到你的媒體庫",
     "ValueSpecialEpisodeName": "特典 - {0}",
-    "VersionNumber": "版本{0}"
+    "VersionNumber": "版本{0}",
+    "TaskDownloadMissingSubtitles": "下載遺失的字幕",
+    "TaskUpdatePlugins": "更新插件",
+    "TasksApplicationCategory": "應用程式"
 }

+ 7 - 1
Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs

@@ -63,6 +63,9 @@ namespace Emby.Server.Implementations.SocketSharp
                     if (!IPAddress.TryParse(GetHeader(CustomHeaderNames.XRealIP), out ip))
                     {
                         ip = Request.HttpContext.Connection.RemoteIpAddress;
+
+                        // Default to the loopback address if no RemoteIpAddress is specified (i.e. during integration tests)
+                        ip ??= IPAddress.Loopback;
                     }
                 }
 
@@ -90,7 +93,10 @@ namespace Emby.Server.Implementations.SocketSharp
 
         public IQueryCollection QueryString => Request.Query;
 
-        public bool IsLocal => Request.HttpContext.Connection.LocalIpAddress.Equals(Request.HttpContext.Connection.RemoteIpAddress);
+        public bool IsLocal =>
+            (Request.HttpContext.Connection.LocalIpAddress == null
+            && Request.HttpContext.Connection.RemoteIpAddress == null)
+            || Request.HttpContext.Connection.LocalIpAddress.Equals(Request.HttpContext.Connection.RemoteIpAddress);
 
         public string HttpMethod => Request.Method;
 

+ 0 - 1140
Jellyfin.Data/DbContexts/Jellyfin.cs

@@ -1,1140 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.ComponentModel.DataAnnotations.Schema;
-using Microsoft.EntityFrameworkCore;
-
-namespace Jellyfin.Data.DbContexts
-{
-   /// <inheritdoc/>
-   public partial class Jellyfin : DbContext
-   {
-      #region DbSets
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Artwork> Artwork { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Book> Books { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.BookMetadata> BookMetadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Chapter> Chapters { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Collection> Collections { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.CollectionItem> CollectionItems { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Company> Companies { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.CompanyMetadata> CompanyMetadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.CustomItem> CustomItems { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.CustomItemMetadata> CustomItemMetadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Episode> Episodes { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.EpisodeMetadata> EpisodeMetadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Genre> Genres { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Group> Groups { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Library> Libraries { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.LibraryItem> LibraryItems { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.LibraryRoot> LibraryRoot { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MediaFile> MediaFiles { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MediaFileStream> MediaFileStream { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Metadata> Metadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MetadataProvider> MetadataProviders { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MetadataProviderId> MetadataProviderIds { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Movie> Movies { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MovieMetadata> MovieMetadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MusicAlbum> MusicAlbums { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MusicAlbumMetadata> MusicAlbumMetadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Permission> Permissions { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Person> People { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.PersonRole> PersonRoles { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Photo> Photo { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.PhotoMetadata> PhotoMetadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Preference> Preferences { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.ProviderMapping> ProviderMappings { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Rating> Ratings { get; set; }
-
-      /// <summary>
-      /// Repository for global::Jellyfin.Data.Entities.RatingSource - This is the entity to
-      /// store review ratings, not age ratings
-      /// </summary>
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.RatingSource> RatingSources { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Release> Releases { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Season> Seasons { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.SeasonMetadata> SeasonMetadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Series> Series { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.SeriesMetadata> SeriesMetadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Track> Tracks { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.TrackMetadata> TrackMetadata { get; set; }
-      public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.User> Users { get; set; }
-      #endregion DbSets
-
-      /// <summary>
-      /// Default connection string
-      /// </summary>
-      public static string ConnectionString { get; set; } = @"Data Source=jellyfin.db";
-
-      /// <inheritdoc />
-      public Jellyfin(DbContextOptions<Jellyfin> options) : base(options)
-      {
-      }
-
-      partial void CustomInit(DbContextOptionsBuilder optionsBuilder);
-
-      /// <inheritdoc />
-      protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
-      {
-         CustomInit(optionsBuilder);
-      }
-
-      partial void OnModelCreatingImpl(ModelBuilder modelBuilder);
-      partial void OnModelCreatedImpl(ModelBuilder modelBuilder);
-
-      /// <inheritdoc />
-      protected override void OnModelCreating(ModelBuilder modelBuilder)
-      {
-         base.OnModelCreating(modelBuilder);
-         OnModelCreatingImpl(modelBuilder);
-
-         modelBuilder.HasDefaultSchema("jellyfin");
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>()
-                     .ToTable("Artwork")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>()
-                     .Property(t => t.Path)
-                     .HasMaxLength(65535)
-                     .IsRequired()
-                     .HasField("_Path")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>()
-                     .Property(t => t.Kind)
-                     .IsRequired()
-                     .HasField("_Kind")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>().HasIndex(t => t.Kind);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Book>()
-                     .HasMany(x => x.BookMetadata)
-                     .WithOne()
-                     .HasForeignKey("BookMetadata_BookMetadata_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Book>()
-                     .HasMany(x => x.Releases)
-                     .WithOne()
-                     .HasForeignKey("Release_Releases_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.BookMetadata>()
-                     .Property(t => t.ISBN)
-                     .HasField("_ISBN")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.BookMetadata>()
-                     .HasMany(x => x.Publishers)
-                     .WithOne()
-                     .HasForeignKey("Company_Publishers_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>()
-                     .ToTable("Chapter")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>()
-                     .Property(t => t.Name)
-                     .HasMaxLength(1024)
-                     .HasField("_Name")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>()
-                     .Property(t => t.Language)
-                     .HasMaxLength(3)
-                     .IsRequired()
-                     .HasField("_Language")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>()
-                     .Property(t => t.TimeStart)
-                     .IsRequired()
-                     .HasField("_TimeStart")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>()
-                     .Property(t => t.TimeEnd)
-                     .HasField("_TimeEnd")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Collection>()
-                     .ToTable("Collection")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Collection>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Collection>()
-                     .Property(t => t.Name)
-                     .HasMaxLength(1024)
-                     .HasField("_Name")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Collection>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Collection>()
-                     .HasMany(x => x.CollectionItem)
-                     .WithOne()
-                     .HasForeignKey("CollectionItem_CollectionItem_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>()
-                     .ToTable("CollectionItem")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>()
-                     .HasOne(x => x.LibraryItem)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.CollectionItem>("LibraryItem_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>()
-                     .HasOne(x => x.Next)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.CollectionItem>("CollectionItem_Next_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>()
-                     .HasOne(x => x.Previous)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.CollectionItem>("CollectionItem_Previous_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Company>()
-                     .ToTable("Company")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Company>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Company>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Company>()
-                     .HasMany(x => x.CompanyMetadata)
-                     .WithOne()
-                     .HasForeignKey("CompanyMetadata_CompanyMetadata_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Company>()
-                     .HasOne(x => x.Parent)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.Company>("Company_Parent_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CompanyMetadata>()
-                     .Property(t => t.Description)
-                     .HasMaxLength(65535)
-                     .HasField("_Description")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CompanyMetadata>()
-                     .Property(t => t.Headquarters)
-                     .HasMaxLength(255)
-                     .HasField("_Headquarters")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CompanyMetadata>()
-                     .Property(t => t.Country)
-                     .HasMaxLength(2)
-                     .HasField("_Country")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CompanyMetadata>()
-                     .Property(t => t.Homepage)
-                     .HasMaxLength(1024)
-                     .HasField("_Homepage")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CustomItem>()
-                     .HasMany(x => x.CustomItemMetadata)
-                     .WithOne()
-                     .HasForeignKey("CustomItemMetadata_CustomItemMetadata_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.CustomItem>()
-                     .HasMany(x => x.Releases)
-                     .WithOne()
-                     .HasForeignKey("Release_Releases_Id")
-                     .IsRequired();
-
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Episode>()
-                     .Property(t => t.EpisodeNumber)
-                     .HasField("_EpisodeNumber")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Episode>()
-                     .HasMany(x => x.Releases)
-                     .WithOne()
-                     .HasForeignKey("Release_Releases_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Episode>()
-                     .HasMany(x => x.EpisodeMetadata)
-                     .WithOne()
-                     .HasForeignKey("EpisodeMetadata_EpisodeMetadata_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.EpisodeMetadata>()
-                     .Property(t => t.Outline)
-                     .HasMaxLength(1024)
-                     .HasField("_Outline")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.EpisodeMetadata>()
-                     .Property(t => t.Plot)
-                     .HasMaxLength(65535)
-                     .HasField("_Plot")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.EpisodeMetadata>()
-                     .Property(t => t.Tagline)
-                     .HasMaxLength(1024)
-                     .HasField("_Tagline")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Genre>()
-                     .ToTable("Genre")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Genre>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Genre>()
-                     .Property(t => t.Name)
-                     .HasMaxLength(255)
-                     .IsRequired()
-                     .HasField("_Name")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Genre>().HasIndex(t => t.Name)
-                     .IsUnique();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Genre>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>()
-                     .ToTable("Groups")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>()
-                     .Property(t => t.Name)
-                     .HasMaxLength(255)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>().Property<byte[]>("Timestamp").IsConcurrencyToken();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>()
-                     .HasMany(x => x.GroupPermissions)
-                     .WithOne()
-                     .HasForeignKey("Permission_GroupPermissions_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>()
-                     .HasMany(x => x.ProviderMappings)
-                     .WithOne()
-                     .HasForeignKey("ProviderMapping_ProviderMappings_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>()
-                     .HasMany(x => x.Preferences)
-                     .WithOne()
-                     .HasForeignKey("Preference_Preferences_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Library>()
-                     .ToTable("Library")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Library>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Library>()
-                     .Property(t => t.Name)
-                     .HasMaxLength(1024)
-                     .IsRequired()
-                     .HasField("_Name")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Library>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>()
-                     .ToTable("LibraryItem")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>()
-                     .Property(t => t.UrlId)
-                     .IsRequired()
-                     .HasField("_UrlId")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>().HasIndex(t => t.UrlId)
-                     .IsUnique();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>()
-                     .Property(t => t.DateAdded)
-                     .IsRequired()
-                     .HasField("_DateAdded")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>()
-                     .HasOne(x => x.LibraryRoot)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.LibraryItem>("LibraryRoot_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>()
-                     .ToTable("LibraryRoot")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>()
-                     .Property(t => t.Path)
-                     .HasMaxLength(65535)
-                     .IsRequired()
-                     .HasField("_Path")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>()
-                     .Property(t => t.NetworkPath)
-                     .HasMaxLength(65535)
-                     .HasField("_NetworkPath")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>()
-                     .HasOne(x => x.Library)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.LibraryRoot>("Library_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>()
-                     .ToTable("MediaFile")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>()
-                     .Property(t => t.Path)
-                     .HasMaxLength(65535)
-                     .IsRequired()
-                     .HasField("_Path")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>()
-                     .Property(t => t.Kind)
-                     .IsRequired()
-                     .HasField("_Kind")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>()
-                     .HasMany(x => x.MediaFileStreams)
-                     .WithOne()
-                     .HasForeignKey("MediaFileStream_MediaFileStreams_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFileStream>()
-                     .ToTable("MediaFileStream")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFileStream>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFileStream>()
-                     .Property(t => t.StreamNumber)
-                     .IsRequired()
-                     .HasField("_StreamNumber")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFileStream>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .ToTable("Metadata")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .Property(t => t.Title)
-                     .HasMaxLength(1024)
-                     .IsRequired()
-                     .HasField("_Title")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .Property(t => t.OriginalTitle)
-                     .HasMaxLength(1024)
-                     .HasField("_OriginalTitle")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .Property(t => t.SortTitle)
-                     .HasMaxLength(1024)
-                     .HasField("_SortTitle")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .Property(t => t.Language)
-                     .HasMaxLength(3)
-                     .IsRequired()
-                     .HasField("_Language")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .Property(t => t.ReleaseDate)
-                     .HasField("_ReleaseDate")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .Property(t => t.DateAdded)
-                     .IsRequired()
-                     .HasField("_DateAdded")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .Property(t => t.DateModified)
-                     .IsRequired()
-                     .HasField("_DateModified")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .HasMany(x => x.PersonRoles)
-                     .WithOne()
-                     .HasForeignKey("PersonRole_PersonRoles_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .HasMany(x => x.Genres)
-                     .WithOne()
-                     .HasForeignKey("Genre_Genres_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .HasMany(x => x.Artwork)
-                     .WithOne()
-                     .HasForeignKey("Artwork_Artwork_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .HasMany(x => x.Ratings)
-                     .WithOne()
-                     .HasForeignKey("Rating_Ratings_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>()
-                     .HasMany(x => x.Sources)
-                     .WithOne()
-                     .HasForeignKey("MetadataProviderId_Sources_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProvider>()
-                     .ToTable("MetadataProvider")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProvider>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProvider>()
-                     .Property(t => t.Name)
-                     .HasMaxLength(1024)
-                     .IsRequired()
-                     .HasField("_Name")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProvider>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProviderId>()
-                     .ToTable("MetadataProviderId")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProviderId>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProviderId>()
-                     .Property(t => t.ProviderId)
-                     .HasMaxLength(255)
-                     .IsRequired()
-                     .HasField("_ProviderId")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProviderId>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProviderId>()
-                     .HasOne(x => x.MetadataProvider)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.MetadataProviderId>("MetadataProvider_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Movie>()
-                     .HasMany(x => x.Releases)
-                     .WithOne()
-                     .HasForeignKey("Release_Releases_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Movie>()
-                     .HasMany(x => x.MovieMetadata)
-                     .WithOne()
-                     .HasForeignKey("MovieMetadata_MovieMetadata_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MovieMetadata>()
-                     .Property(t => t.Outline)
-                     .HasMaxLength(1024)
-                     .HasField("_Outline")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MovieMetadata>()
-                     .Property(t => t.Plot)
-                     .HasMaxLength(65535)
-                     .HasField("_Plot")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MovieMetadata>()
-                     .Property(t => t.Tagline)
-                     .HasMaxLength(1024)
-                     .HasField("_Tagline")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MovieMetadata>()
-                     .Property(t => t.Country)
-                     .HasMaxLength(2)
-                     .HasField("_Country")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MovieMetadata>()
-                     .HasMany(x => x.Studios)
-                     .WithOne()
-                     .HasForeignKey("Company_Studios_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbum>()
-                     .HasMany(x => x.MusicAlbumMetadata)
-                     .WithOne()
-                     .HasForeignKey("MusicAlbumMetadata_MusicAlbumMetadata_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbum>()
-                     .HasMany(x => x.Tracks)
-                     .WithOne()
-                     .HasForeignKey("Track_Tracks_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbumMetadata>()
-                     .Property(t => t.Barcode)
-                     .HasMaxLength(255)
-                     .HasField("_Barcode")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbumMetadata>()
-                     .Property(t => t.LabelNumber)
-                     .HasMaxLength(255)
-                     .HasField("_LabelNumber")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbumMetadata>()
-                     .Property(t => t.Country)
-                     .HasMaxLength(2)
-                     .HasField("_Country")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbumMetadata>()
-                     .HasMany(x => x.Labels)
-                     .WithOne()
-                     .HasForeignKey("Company_Labels_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Permission>()
-                     .ToTable("Permissions")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Permission>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Permission>()
-                     .Property(t => t.Kind)
-                     .IsRequired()
-                     .HasField("_Kind")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Permission>()
-                     .Property(t => t.Value)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Permission>().Property<byte[]>("Timestamp").IsConcurrencyToken();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>()
-                     .ToTable("Person")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>()
-                     .Property(t => t.UrlId)
-                     .IsRequired()
-                     .HasField("_UrlId")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>()
-                     .Property(t => t.Name)
-                     .HasMaxLength(1024)
-                     .IsRequired()
-                     .HasField("_Name")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>()
-                     .Property(t => t.SourceId)
-                     .HasMaxLength(255)
-                     .HasField("_SourceId")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>()
-                     .Property(t => t.DateAdded)
-                     .IsRequired()
-                     .HasField("_DateAdded")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>()
-                     .Property(t => t.DateModified)
-                     .IsRequired()
-                     .HasField("_DateModified")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>()
-                     .HasMany(x => x.Sources)
-                     .WithOne()
-                     .HasForeignKey("MetadataProviderId_Sources_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>()
-                     .ToTable("PersonRole")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>()
-                     .Property(t => t.Role)
-                     .HasMaxLength(1024)
-                     .HasField("_Role")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>()
-                     .Property(t => t.Type)
-                     .IsRequired()
-                     .HasField("_Type")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>()
-                     .HasOne(x => x.Person)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.PersonRole>("Person_Id")
-                     .IsRequired()
-                     .OnDelete(DeleteBehavior.Cascade);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>()
-                     .HasOne(x => x.Artwork)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.PersonRole>("Artwork_Artwork_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>()
-                     .HasMany(x => x.Sources)
-                     .WithOne()
-                     .HasForeignKey("MetadataProviderId_Sources_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Photo>()
-                     .HasMany(x => x.PhotoMetadata)
-                     .WithOne()
-                     .HasForeignKey("PhotoMetadata_PhotoMetadata_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Photo>()
-                     .HasMany(x => x.Releases)
-                     .WithOne()
-                     .HasForeignKey("Release_Releases_Id")
-                     .IsRequired();
-
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Preference>()
-                     .ToTable("Preferences")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Preference>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Preference>()
-                     .Property(t => t.Kind)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Preference>()
-                     .Property(t => t.Value)
-                     .HasMaxLength(65535)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Preference>().Property<byte[]>("Timestamp").IsConcurrencyToken();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>()
-                     .ToTable("ProviderMappings")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>()
-                     .Property(t => t.ProviderName)
-                     .HasMaxLength(255)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>()
-                     .Property(t => t.ProviderSecrets)
-                     .HasMaxLength(65535)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>()
-                     .Property(t => t.ProviderData)
-                     .HasMaxLength(65535)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>().Property<byte[]>("Timestamp").IsConcurrencyToken();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>()
-                     .ToTable("Rating")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>()
-                     .Property(t => t.Value)
-                     .IsRequired()
-                     .HasField("_Value")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>()
-                     .Property(t => t.Votes)
-                     .HasField("_Votes")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>()
-                     .HasOne(x => x.RatingType)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.Rating>("RatingSource_RatingType_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>()
-                     .ToTable("RatingType")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>()
-                     .Property(t => t.Name)
-                     .HasMaxLength(1024)
-                     .HasField("_Name")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>()
-                     .Property(t => t.MaximumValue)
-                     .IsRequired()
-                     .HasField("_MaximumValue")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>()
-                     .Property(t => t.MinimumValue)
-                     .IsRequired()
-                     .HasField("_MinimumValue")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>()
-                     .HasOne(x => x.Source)
-                     .WithOne()
-                     .HasForeignKey<global::Jellyfin.Data.Entities.RatingSource>("MetadataProviderId_Source_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>()
-                     .ToTable("Release")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .HasField("_Id")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>()
-                     .Property(t => t.Name)
-                     .HasMaxLength(1024)
-                     .IsRequired()
-                     .HasField("_Name")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>()
-                     .Property(t => t.Timestamp)
-                     .IsRequired()
-                     .HasField("_Timestamp")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property)
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>()
-                     .HasMany(x => x.MediaFiles)
-                     .WithOne()
-                     .HasForeignKey("MediaFile_MediaFiles_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>()
-                     .HasMany(x => x.Chapters)
-                     .WithOne()
-                     .HasForeignKey("Chapter_Chapters_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Season>()
-                     .Property(t => t.SeasonNumber)
-                     .HasField("_SeasonNumber")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Season>()
-                     .HasMany(x => x.SeasonMetadata)
-                     .WithOne()
-                     .HasForeignKey("SeasonMetadata_SeasonMetadata_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Season>()
-                     .HasMany(x => x.Episodes)
-                     .WithOne()
-                     .HasForeignKey("Episode_Episodes_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.SeasonMetadata>()
-                     .Property(t => t.Outline)
-                     .HasMaxLength(1024)
-                     .HasField("_Outline")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Series>()
-                     .Property(t => t.AirsDayOfWeek)
-                     .HasField("_AirsDayOfWeek")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Series>()
-                     .Property(t => t.AirsTime)
-                     .HasField("_AirsTime")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Series>()
-                     .Property(t => t.FirstAired)
-                     .HasField("_FirstAired")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Series>()
-                     .HasMany(x => x.SeriesMetadata)
-                     .WithOne()
-                     .HasForeignKey("SeriesMetadata_SeriesMetadata_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Series>()
-                     .HasMany(x => x.Seasons)
-                     .WithOne()
-                     .HasForeignKey("Season_Seasons_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.SeriesMetadata>()
-                     .Property(t => t.Outline)
-                     .HasMaxLength(1024)
-                     .HasField("_Outline")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.SeriesMetadata>()
-                     .Property(t => t.Plot)
-                     .HasMaxLength(65535)
-                     .HasField("_Plot")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.SeriesMetadata>()
-                     .Property(t => t.Tagline)
-                     .HasMaxLength(1024)
-                     .HasField("_Tagline")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.SeriesMetadata>()
-                     .Property(t => t.Country)
-                     .HasMaxLength(2)
-                     .HasField("_Country")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.SeriesMetadata>()
-                     .HasMany(x => x.Networks)
-                     .WithOne()
-                     .HasForeignKey("Company_Networks_Id")
-                     .IsRequired();
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Track>()
-                     .Property(t => t.TrackNumber)
-                     .HasField("_TrackNumber")
-                     .UsePropertyAccessMode(PropertyAccessMode.Property);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Track>()
-                     .HasMany(x => x.Releases)
-                     .WithOne()
-                     .HasForeignKey("Release_Releases_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.Track>()
-                     .HasMany(x => x.TrackMetadata)
-                     .WithOne()
-                     .HasForeignKey("TrackMetadata_TrackMetadata_Id")
-                     .IsRequired();
-
-
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .ToTable("Users")
-                     .HasKey(t => t.Id);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.Id)
-                     .IsRequired()
-                     .ValueGeneratedOnAdd();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.LastLoginTimestamp)
-                     .IsRequired()
-                     .IsRowVersion();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.Username)
-                     .HasMaxLength(255)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.Password)
-                     .HasMaxLength(65535);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.MustUpdatePassword)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.AudioLanguagePreference)
-                     .HasMaxLength(255)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.AuthenticationProviderId)
-                     .HasMaxLength(255)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.GroupedFolders)
-                     .HasMaxLength(65535);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.InvalidLoginAttemptCount)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.LatestItemExcludes)
-                     .HasMaxLength(65535);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.MyMediaExcludes)
-                     .HasMaxLength(65535);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.OrderedViews)
-                     .HasMaxLength(65535);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.SubtitleMode)
-                     .HasMaxLength(255)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.PlayDefaultAudioTrack)
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .Property(t => t.SubtitleLanguagePrefernce)
-                     .HasMaxLength(255);
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .HasMany(x => x.Groups)
-                     .WithOne()
-                     .HasForeignKey("Group_Groups_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .HasMany(x => x.Permissions)
-                     .WithOne()
-                     .HasForeignKey("Permission_Permissions_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .HasMany(x => x.ProviderMappings)
-                     .WithOne()
-                     .HasForeignKey("ProviderMapping_ProviderMappings_Id")
-                     .IsRequired();
-         modelBuilder.Entity<global::Jellyfin.Data.Entities.User>()
-                     .HasMany(x => x.Preferences)
-                     .WithOne()
-                     .HasForeignKey("Preference_Preferences_Id")
-                     .IsRequired();
-
-         OnModelCreatedImpl(modelBuilder);
-      }
-   }
-}

+ 179 - 192
Jellyfin.Data/Entities/Artwork.cs

@@ -1,208 +1,195 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Artwork
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Artwork()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Artwork CreateArtworkUnsafe()
-      {
-         return new Artwork();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="path"></param>
-      /// <param name="kind"></param>
-      /// <param name="_metadata0"></param>
-      /// <param name="_personrole1"></param>
-      public Artwork(string path, global::Jellyfin.Data.Enums.ArtKind kind, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.PersonRole _personrole1)
-      {
-         if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
-         this.Path = path;
-
-         this.Kind = kind;
-
-         if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
-         _metadata0.Artwork.Add(this);
-
-         if (_personrole1 == null) throw new ArgumentNullException(nameof(_personrole1));
-         _personrole1.Artwork = this;
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="path"></param>
-      /// <param name="kind"></param>
-      /// <param name="_metadata0"></param>
-      /// <param name="_personrole1"></param>
-      public static Artwork Create(string path, global::Jellyfin.Data.Enums.ArtKind kind, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.PersonRole _personrole1)
-      {
-         return new Artwork(path, kind, _metadata0, _personrole1);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Artwork
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Artwork()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Artwork CreateArtworkUnsafe()
+        {
+            return new Artwork();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="path"></param>
+        /// <param name="kind"></param>
+        /// <param name="_metadata0"></param>
+        /// <param name="_personrole1"></param>
+        public Artwork(string path, Enums.ArtKind kind, Metadata _metadata0, PersonRole _personrole1)
+        {
+            if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
+            this.Path = path;
+
+            this.Kind = kind;
+
+            if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
+            _metadata0.Artwork.Add(this);
+
+            if (_personrole1 == null) throw new ArgumentNullException(nameof(_personrole1));
+            _personrole1.Artwork = this;
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="path"></param>
+        /// <param name="kind"></param>
+        /// <param name="_metadata0"></param>
+        /// <param name="_personrole1"></param>
+        public static Artwork Create(string path, Enums.ArtKind kind, Metadata _metadata0, PersonRole _personrole1)
+        {
+            return new Artwork(path, kind, _metadata0, _personrole1);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
+            {
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Path
+        /// </summary>
+        protected string _Path;
+        /// <summary>
+        /// When provided in a partial class, allows value of Path to be changed before setting.
+        /// </summary>
+        partial void SetPath(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Path to be changed before returning.
+        /// </summary>
+        partial void GetPath(ref string result);
+
+        /// <summary>
+        /// Required, Max length = 65535
+        /// </summary>
+        [Required]
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string Path
+        {
+            get
+            {
+                string value = _Path;
+                GetPath(ref value);
+                return (_Path = value);
+            }
+            set
             {
-               _Id = value;
+                string oldValue = _Path;
+                SetPath(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Path = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Path
-      /// </summary>
-      protected string _Path;
-      /// <summary>
-      /// When provided in a partial class, allows value of Path to be changed before setting.
-      /// </summary>
-      partial void SetPath(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Path to be changed before returning.
-      /// </summary>
-      partial void GetPath(ref string result);
-
-      /// <summary>
-      /// Required, Max length = 65535
-      /// </summary>
-      [Required]
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string Path
-      {
-         get
-         {
-            string value = _Path;
-            GetPath(ref value);
-            return (_Path = value);
-         }
-         set
-         {
-            string oldValue = _Path;
-            SetPath(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Kind
+        /// </summary>
+        internal Enums.ArtKind _Kind;
+        /// <summary>
+        /// When provided in a partial class, allows value of Kind to be changed before setting.
+        /// </summary>
+        partial void SetKind(Enums.ArtKind oldValue, ref Enums.ArtKind newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Kind to be changed before returning.
+        /// </summary>
+        partial void GetKind(ref Enums.ArtKind result);
+
+        /// <summary>
+        /// Indexed, Required
+        /// </summary>
+        [Required]
+        public Enums.ArtKind Kind
+        {
+            get
             {
-               _Path = value;
+                Enums.ArtKind value = _Kind;
+                GetKind(ref value);
+                return (_Kind = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Kind
-      /// </summary>
-      internal global::Jellyfin.Data.Enums.ArtKind _Kind;
-      /// <summary>
-      /// When provided in a partial class, allows value of Kind to be changed before setting.
-      /// </summary>
-      partial void SetKind(global::Jellyfin.Data.Enums.ArtKind oldValue, ref global::Jellyfin.Data.Enums.ArtKind newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Kind to be changed before returning.
-      /// </summary>
-      partial void GetKind(ref global::Jellyfin.Data.Enums.ArtKind result);
-
-      /// <summary>
-      /// Indexed, Required
-      /// </summary>
-      [Required]
-      public global::Jellyfin.Data.Enums.ArtKind Kind
-      {
-         get
-         {
-            global::Jellyfin.Data.Enums.ArtKind value = _Kind;
-            GetKind(ref value);
-            return (_Kind = value);
-         }
-         set
-         {
-            global::Jellyfin.Data.Enums.ArtKind oldValue = _Kind;
-            SetKind(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Kind = value;
+                Enums.ArtKind oldValue = _Kind;
+                SetKind(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Kind = value;
+                }
             }
-         }
-      }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 49 - 64
Jellyfin.Data/Entities/Book.cs

@@ -1,84 +1,69 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Book: global::Jellyfin.Data.Entities.LibraryItem
-   {
-      partial void Init();
+    public partial class Book : LibraryItem
+    {
+        partial void Init();
 
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Book(): base()
-      {
-         BookMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.BookMetadata>();
-         Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Book()
+        {
+            BookMetadata = new HashSet<BookMetadata>();
+            Releases = new HashSet<Release>();
 
-         Init();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Book CreateBookUnsafe()
-      {
-         return new Book();
-      }
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Book CreateBookUnsafe()
+        {
+            return new Book();
+        }
 
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public Book(Guid urlid, DateTime dateadded)
-      {
-         this.UrlId = urlid;
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public Book(Guid urlid, DateTime dateadded)
+        {
+            this.UrlId = urlid;
 
-         this.BookMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.BookMetadata>();
-         this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
+            this.BookMetadata = new HashSet<BookMetadata>();
+            this.Releases = new HashSet<Release>();
 
-         Init();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public static Book Create(Guid urlid, DateTime dateadded)
-      {
-         return new Book(urlid, dateadded);
-      }
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public static Book Create(Guid urlid, DateTime dateadded)
+        {
+            return new Book(urlid, dateadded);
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.BookMetadata> BookMetadata { get; protected set; }
+        [ForeignKey("BookMetadata_BookMetadata_Id")]
+        public virtual ICollection<BookMetadata> BookMetadata { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
+        [ForeignKey("Release_Releases_Id")]
+        public virtual ICollection<Release> Releases { get; protected set; }
 
-   }
+    }
 }
 

+ 94 - 110
Jellyfin.Data/Entities/BookMetadata.cs

@@ -1,123 +1,107 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class BookMetadata: global::Jellyfin.Data.Entities.Metadata
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected BookMetadata(): base()
-      {
-         Publishers = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static BookMetadata CreateBookMetadataUnsafe()
-      {
-         return new BookMetadata();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_book0"></param>
-      public BookMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Book _book0)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
-
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
-
-         if (_book0 == null) throw new ArgumentNullException(nameof(_book0));
-         _book0.BookMetadata.Add(this);
-
-         this.Publishers = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_book0"></param>
-      public static BookMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Book _book0)
-      {
-         return new BookMetadata(title, language, dateadded, datemodified, _book0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for ISBN
-      /// </summary>
-      protected long? _ISBN;
-      /// <summary>
-      /// When provided in a partial class, allows value of ISBN to be changed before setting.
-      /// </summary>
-      partial void SetISBN(long? oldValue, ref long? newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of ISBN to be changed before returning.
-      /// </summary>
-      partial void GetISBN(ref long? result);
-
-      public long? ISBN
-      {
-         get
-         {
-            long? value = _ISBN;
-            GetISBN(ref value);
-            return (_ISBN = value);
-         }
-         set
-         {
-            long? oldValue = _ISBN;
-            SetISBN(oldValue, ref value);
-            if (oldValue != value)
+    public partial class BookMetadata : Metadata
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected BookMetadata()
+        {
+            Publishers = new HashSet<Company>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static BookMetadata CreateBookMetadataUnsafe()
+        {
+            return new BookMetadata();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_book0"></param>
+        public BookMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Book _book0)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
+
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
+
+            if (_book0 == null) throw new ArgumentNullException(nameof(_book0));
+            _book0.BookMetadata.Add(this);
+
+            this.Publishers = new HashSet<Company>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_book0"></param>
+        public static BookMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Book _book0)
+        {
+            return new BookMetadata(title, language, dateadded, datemodified, _book0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for ISBN
+        /// </summary>
+        protected long? _ISBN;
+        /// <summary>
+        /// When provided in a partial class, allows value of ISBN to be changed before setting.
+        /// </summary>
+        partial void SetISBN(long? oldValue, ref long? newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of ISBN to be changed before returning.
+        /// </summary>
+        partial void GetISBN(ref long? result);
+
+        public long? ISBN
+        {
+            get
+            {
+                long? value = _ISBN;
+                GetISBN(ref value);
+                return (_ISBN = value);
+            }
+            set
             {
-               _ISBN = value;
+                long? oldValue = _ISBN;
+                SetISBN(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _ISBN = value;
+                }
             }
-         }
-      }
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Company> Publishers { get; protected set; }
+        [ForeignKey("Company_Publishers_Id")]
+        public virtual ICollection<Company> Publishers { get; protected set; }
 
-   }
+    }
 }
 

+ 223 - 234
Jellyfin.Data/Entities/Chapter.cs

@@ -1,274 +1,263 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Chapter
-   {
-      partial void Init();
+    public partial class Chapter
+    {
+        partial void Init();
 
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Chapter()
-      {
-         Init();
-      }
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Chapter()
+        {
+            Init();
+        }
 
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Chapter CreateChapterUnsafe()
-      {
-         return new Chapter();
-      }
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Chapter CreateChapterUnsafe()
+        {
+            return new Chapter();
+        }
 
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="timestart"></param>
-      /// <param name="_release0"></param>
-      public Chapter(string language, long timestart, global::Jellyfin.Data.Entities.Release _release0)
-      {
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="timestart"></param>
+        /// <param name="_release0"></param>
+        public Chapter(string language, long timestart, Release _release0)
+        {
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
 
-         this.TimeStart = timestart;
+            this.TimeStart = timestart;
 
-         if (_release0 == null) throw new ArgumentNullException(nameof(_release0));
-         _release0.Chapters.Add(this);
+            if (_release0 == null) throw new ArgumentNullException(nameof(_release0));
+            _release0.Chapters.Add(this);
 
 
-         Init();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="timestart"></param>
-      /// <param name="_release0"></param>
-      public static Chapter Create(string language, long timestart, global::Jellyfin.Data.Entities.Release _release0)
-      {
-         return new Chapter(language, timestart, _release0);
-      }
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="timestart"></param>
+        /// <param name="_release0"></param>
+        public static Chapter Create(string language, long timestart, Release _release0)
+        {
+            return new Chapter(language, timestart, _release0);
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
 
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
             {
-               _Id = value;
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
             }
-         }
-      }
+        }
 
-      /// <summary>
-      /// Backing field for Name
-      /// </summary>
-      protected string _Name;
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before setting.
-      /// </summary>
-      partial void SetName(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before returning.
-      /// </summary>
-      partial void GetName(ref string result);
+        /// <summary>
+        /// Backing field for Name
+        /// </summary>
+        protected string _Name;
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before setting.
+        /// </summary>
+        partial void SetName(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before returning.
+        /// </summary>
+        partial void GetName(ref string result);
 
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Name
-      {
-         get
-         {
-            string value = _Name;
-            GetName(ref value);
-            return (_Name = value);
-         }
-         set
-         {
-            string oldValue = _Name;
-            SetName(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Name
+        {
+            get
             {
-               _Name = value;
+                string value = _Name;
+                GetName(ref value);
+                return (_Name = value);
             }
-         }
-      }
+            set
+            {
+                string oldValue = _Name;
+                SetName(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Name = value;
+                }
+            }
+        }
 
-      /// <summary>
-      /// Backing field for Language
-      /// </summary>
-      protected string _Language;
-      /// <summary>
-      /// When provided in a partial class, allows value of Language to be changed before setting.
-      /// </summary>
-      partial void SetLanguage(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Language to be changed before returning.
-      /// </summary>
-      partial void GetLanguage(ref string result);
+        /// <summary>
+        /// Backing field for Language
+        /// </summary>
+        protected string _Language;
+        /// <summary>
+        /// When provided in a partial class, allows value of Language to be changed before setting.
+        /// </summary>
+        partial void SetLanguage(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Language to be changed before returning.
+        /// </summary>
+        partial void GetLanguage(ref string result);
 
-      /// <summary>
-      /// Required, Min length = 3, Max length = 3
-      /// ISO-639-3 3-character language codes
-      /// </summary>
-      [Required]
-      [MinLength(3)]
-      [MaxLength(3)]
-      [StringLength(3)]
-      public string Language
-      {
-         get
-         {
-            string value = _Language;
-            GetLanguage(ref value);
-            return (_Language = value);
-         }
-         set
-         {
-            string oldValue = _Language;
-            SetLanguage(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Required, Min length = 3, Max length = 3
+        /// ISO-639-3 3-character language codes
+        /// </summary>
+        [Required]
+        [MinLength(3)]
+        [MaxLength(3)]
+        [StringLength(3)]
+        public string Language
+        {
+            get
+            {
+                string value = _Language;
+                GetLanguage(ref value);
+                return (_Language = value);
+            }
+            set
             {
-               _Language = value;
+                string oldValue = _Language;
+                SetLanguage(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Language = value;
+                }
             }
-         }
-      }
+        }
 
-      /// <summary>
-      /// Backing field for TimeStart
-      /// </summary>
-      protected long _TimeStart;
-      /// <summary>
-      /// When provided in a partial class, allows value of TimeStart to be changed before setting.
-      /// </summary>
-      partial void SetTimeStart(long oldValue, ref long newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of TimeStart to be changed before returning.
-      /// </summary>
-      partial void GetTimeStart(ref long result);
+        /// <summary>
+        /// Backing field for TimeStart
+        /// </summary>
+        protected long _TimeStart;
+        /// <summary>
+        /// When provided in a partial class, allows value of TimeStart to be changed before setting.
+        /// </summary>
+        partial void SetTimeStart(long oldValue, ref long newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of TimeStart to be changed before returning.
+        /// </summary>
+        partial void GetTimeStart(ref long result);
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public long TimeStart
-      {
-         get
-         {
-            long value = _TimeStart;
-            GetTimeStart(ref value);
-            return (_TimeStart = value);
-         }
-         set
-         {
-            long oldValue = _TimeStart;
-            SetTimeStart(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public long TimeStart
+        {
+            get
+            {
+                long value = _TimeStart;
+                GetTimeStart(ref value);
+                return (_TimeStart = value);
+            }
+            set
             {
-               _TimeStart = value;
+                long oldValue = _TimeStart;
+                SetTimeStart(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _TimeStart = value;
+                }
             }
-         }
-      }
+        }
 
-      /// <summary>
-      /// Backing field for TimeEnd
-      /// </summary>
-      protected long? _TimeEnd;
-      /// <summary>
-      /// When provided in a partial class, allows value of TimeEnd to be changed before setting.
-      /// </summary>
-      partial void SetTimeEnd(long? oldValue, ref long? newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of TimeEnd to be changed before returning.
-      /// </summary>
-      partial void GetTimeEnd(ref long? result);
+        /// <summary>
+        /// Backing field for TimeEnd
+        /// </summary>
+        protected long? _TimeEnd;
+        /// <summary>
+        /// When provided in a partial class, allows value of TimeEnd to be changed before setting.
+        /// </summary>
+        partial void SetTimeEnd(long? oldValue, ref long? newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of TimeEnd to be changed before returning.
+        /// </summary>
+        partial void GetTimeEnd(ref long? result);
 
-      public long? TimeEnd
-      {
-         get
-         {
-            long? value = _TimeEnd;
-            GetTimeEnd(ref value);
-            return (_TimeEnd = value);
-         }
-         set
-         {
-            long? oldValue = _TimeEnd;
-            SetTimeEnd(oldValue, ref value);
-            if (oldValue != value)
+        public long? TimeEnd
+        {
+            get
             {
-               _TimeEnd = value;
+                long? value = _TimeEnd;
+                GetTimeEnd(ref value);
+                return (_TimeEnd = value);
             }
-         }
-      }
+            set
+            {
+                long? oldValue = _TimeEnd;
+                SetTimeEnd(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _TimeEnd = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 97 - 108
Jellyfin.Data/Entities/Collection.cs

@@ -1,131 +1,120 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Collection
-   {
-      partial void Init();
+    public partial class Collection
+    {
+        partial void Init();
 
-      /// <summary>
-      /// Default constructor
-      /// </summary>
-      public Collection()
-      {
-         CollectionItem = new System.Collections.Generic.LinkedList<global::Jellyfin.Data.Entities.CollectionItem>();
+        /// <summary>
+        /// Default constructor
+        /// </summary>
+        public Collection()
+        {
+            CollectionItem = new LinkedList<CollectionItem>();
 
-         Init();
-      }
+            Init();
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
 
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
             {
-               _Id = value;
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
             }
-         }
-      }
+        }
 
-      /// <summary>
-      /// Backing field for Name
-      /// </summary>
-      protected string _Name;
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before setting.
-      /// </summary>
-      partial void SetName(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before returning.
-      /// </summary>
-      partial void GetName(ref string result);
+        /// <summary>
+        /// Backing field for Name
+        /// </summary>
+        protected string _Name;
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before setting.
+        /// </summary>
+        partial void SetName(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before returning.
+        /// </summary>
+        partial void GetName(ref string result);
 
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Name
-      {
-         get
-         {
-            string value = _Name;
-            GetName(ref value);
-            return (_Name = value);
-         }
-         set
-         {
-            string oldValue = _Name;
-            SetName(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Name
+        {
+            get
+            {
+                string value = _Name;
+                GetName(ref value);
+                return (_Name = value);
+            }
+            set
             {
-               _Name = value;
+                string oldValue = _Name;
+                SetName(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Name = value;
+                }
             }
-         }
-      }
+        }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.CollectionItem> CollectionItem { get; protected set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("CollectionItem_CollectionItem_Id")]
+        public virtual ICollection<CollectionItem> CollectionItem { get; protected set; }
 
-   }
+    }
 }
 

+ 133 - 141
Jellyfin.Data/Entities/CollectionItem.cs

@@ -1,151 +1,143 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class CollectionItem
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected CollectionItem()
-      {
-         // NOTE: This class has one-to-one associations with CollectionItem.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static CollectionItem CreateCollectionItemUnsafe()
-      {
-         return new CollectionItem();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="_collection0"></param>
-      /// <param name="_collectionitem1"></param>
-      /// <param name="_collectionitem2"></param>
-      public CollectionItem(global::Jellyfin.Data.Entities.Collection _collection0, global::Jellyfin.Data.Entities.CollectionItem _collectionitem1, global::Jellyfin.Data.Entities.CollectionItem _collectionitem2)
-      {
-         // NOTE: This class has one-to-one associations with CollectionItem.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         if (_collection0 == null) throw new ArgumentNullException(nameof(_collection0));
-         _collection0.CollectionItem.Add(this);
-
-         if (_collectionitem1 == null) throw new ArgumentNullException(nameof(_collectionitem1));
-         _collectionitem1.Next = this;
-
-         if (_collectionitem2 == null) throw new ArgumentNullException(nameof(_collectionitem2));
-         _collectionitem2.Previous = this;
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="_collection0"></param>
-      /// <param name="_collectionitem1"></param>
-      /// <param name="_collectionitem2"></param>
-      public static CollectionItem Create(global::Jellyfin.Data.Entities.Collection _collection0, global::Jellyfin.Data.Entities.CollectionItem _collectionitem1, global::Jellyfin.Data.Entities.CollectionItem _collectionitem2)
-      {
-         return new CollectionItem(_collection0, _collectionitem1, _collectionitem2);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class CollectionItem
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected CollectionItem()
+        {
+            // NOTE: This class has one-to-one associations with CollectionItem.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static CollectionItem CreateCollectionItemUnsafe()
+        {
+            return new CollectionItem();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="_collection0"></param>
+        /// <param name="_collectionitem1"></param>
+        /// <param name="_collectionitem2"></param>
+        public CollectionItem(Collection _collection0, CollectionItem _collectionitem1, CollectionItem _collectionitem2)
+        {
+            // NOTE: This class has one-to-one associations with CollectionItem.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            if (_collection0 == null) throw new ArgumentNullException(nameof(_collection0));
+            _collection0.CollectionItem.Add(this);
+
+            if (_collectionitem1 == null) throw new ArgumentNullException(nameof(_collectionitem1));
+            _collectionitem1.Next = this;
+
+            if (_collectionitem2 == null) throw new ArgumentNullException(nameof(_collectionitem2));
+            _collectionitem2.Previous = this;
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="_collection0"></param>
+        /// <param name="_collectionitem1"></param>
+        /// <param name="_collectionitem2"></param>
+        public static CollectionItem Create(Collection _collection0, CollectionItem _collectionitem1, CollectionItem _collectionitem2)
+        {
+            return new CollectionItem(_collection0, _collectionitem1, _collectionitem2);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
             {
-               _Id = value;
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      public virtual global::Jellyfin.Data.Entities.LibraryItem LibraryItem { get; set; }
-
-      /// <remarks>
-      /// TODO check if this properly updated dependant and has the proper principal relationship
-      /// </remarks>
-      public virtual global::Jellyfin.Data.Entities.CollectionItem Next { get; set; }
-
-      /// <remarks>
-      /// TODO check if this properly updated dependant and has the proper principal relationship
-      /// </remarks>
-      public virtual global::Jellyfin.Data.Entities.CollectionItem Previous { get; set; }
-
-   }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [ForeignKey("LibraryItem_Id")]
+        public virtual LibraryItem LibraryItem { get; set; }
+
+        /// <remarks>
+        /// TODO check if this properly updated dependant and has the proper principal relationship
+        /// </remarks>
+        [ForeignKey("CollectionItem_Next_Id")]
+        public virtual CollectionItem Next { get; set; }
+
+        /// <remarks>
+        /// TODO check if this properly updated dependant and has the proper principal relationship
+        /// </remarks>
+        [ForeignKey("CollectionItem_Previous_Id")]
+        public virtual CollectionItem Previous { get; set; }
+
+    }
 }
 

+ 126 - 136
Jellyfin.Data/Entities/Company.cs

@@ -1,147 +1,137 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Company
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Company()
-      {
-         CompanyMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CompanyMetadata>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Company CreateCompanyUnsafe()
-      {
-         return new Company();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="_moviemetadata0"></param>
-      /// <param name="_seriesmetadata1"></param>
-      /// <param name="_musicalbummetadata2"></param>
-      /// <param name="_bookmetadata3"></param>
-      /// <param name="_company4"></param>
-      public Company(global::Jellyfin.Data.Entities.MovieMetadata _moviemetadata0, global::Jellyfin.Data.Entities.SeriesMetadata _seriesmetadata1, global::Jellyfin.Data.Entities.MusicAlbumMetadata _musicalbummetadata2, global::Jellyfin.Data.Entities.BookMetadata _bookmetadata3, global::Jellyfin.Data.Entities.Company _company4)
-      {
-         if (_moviemetadata0 == null) throw new ArgumentNullException(nameof(_moviemetadata0));
-         _moviemetadata0.Studios.Add(this);
-
-         if (_seriesmetadata1 == null) throw new ArgumentNullException(nameof(_seriesmetadata1));
-         _seriesmetadata1.Networks.Add(this);
-
-         if (_musicalbummetadata2 == null) throw new ArgumentNullException(nameof(_musicalbummetadata2));
-         _musicalbummetadata2.Labels.Add(this);
-
-         if (_bookmetadata3 == null) throw new ArgumentNullException(nameof(_bookmetadata3));
-         _bookmetadata3.Publishers.Add(this);
-
-         if (_company4 == null) throw new ArgumentNullException(nameof(_company4));
-         _company4.Parent = this;
-
-         this.CompanyMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CompanyMetadata>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="_moviemetadata0"></param>
-      /// <param name="_seriesmetadata1"></param>
-      /// <param name="_musicalbummetadata2"></param>
-      /// <param name="_bookmetadata3"></param>
-      /// <param name="_company4"></param>
-      public static Company Create(global::Jellyfin.Data.Entities.MovieMetadata _moviemetadata0, global::Jellyfin.Data.Entities.SeriesMetadata _seriesmetadata1, global::Jellyfin.Data.Entities.MusicAlbumMetadata _musicalbummetadata2, global::Jellyfin.Data.Entities.BookMetadata _bookmetadata3, global::Jellyfin.Data.Entities.Company _company4)
-      {
-         return new Company(_moviemetadata0, _seriesmetadata1, _musicalbummetadata2, _bookmetadata3, _company4);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Company
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Company()
+        {
+            CompanyMetadata = new HashSet<CompanyMetadata>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Company CreateCompanyUnsafe()
+        {
+            return new Company();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="_moviemetadata0"></param>
+        /// <param name="_seriesmetadata1"></param>
+        /// <param name="_musicalbummetadata2"></param>
+        /// <param name="_bookmetadata3"></param>
+        /// <param name="_company4"></param>
+        public Company(MovieMetadata _moviemetadata0, SeriesMetadata _seriesmetadata1, MusicAlbumMetadata _musicalbummetadata2, BookMetadata _bookmetadata3, Company _company4)
+        {
+            if (_moviemetadata0 == null) throw new ArgumentNullException(nameof(_moviemetadata0));
+            _moviemetadata0.Studios.Add(this);
+
+            if (_seriesmetadata1 == null) throw new ArgumentNullException(nameof(_seriesmetadata1));
+            _seriesmetadata1.Networks.Add(this);
+
+            if (_musicalbummetadata2 == null) throw new ArgumentNullException(nameof(_musicalbummetadata2));
+            _musicalbummetadata2.Labels.Add(this);
+
+            if (_bookmetadata3 == null) throw new ArgumentNullException(nameof(_bookmetadata3));
+            _bookmetadata3.Publishers.Add(this);
+
+            if (_company4 == null) throw new ArgumentNullException(nameof(_company4));
+            _company4.Parent = this;
+
+            this.CompanyMetadata = new HashSet<CompanyMetadata>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="_moviemetadata0"></param>
+        /// <param name="_seriesmetadata1"></param>
+        /// <param name="_musicalbummetadata2"></param>
+        /// <param name="_bookmetadata3"></param>
+        /// <param name="_company4"></param>
+        public static Company Create(MovieMetadata _moviemetadata0, SeriesMetadata _seriesmetadata1, MusicAlbumMetadata _musicalbummetadata2, BookMetadata _bookmetadata3, Company _company4)
+        {
+            return new Company(_moviemetadata0, _seriesmetadata1, _musicalbummetadata2, _bookmetadata3, _company4);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
             {
-               _Id = value;
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.CompanyMetadata> CompanyMetadata { get; protected set; }
-
-      public virtual global::Jellyfin.Data.Entities.Company Parent { get; set; }
-
-   }
+            protected set
+            {
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("CompanyMetadata_CompanyMetadata_Id")]
+        public virtual ICollection<CompanyMetadata> CompanyMetadata { get; protected set; }
+        [ForeignKey("Company_Parent_Id")]
+        public virtual Company Parent { get; set; }
+
+    }
 }
 

+ 199 - 217
Jellyfin.Data/Entities/CompanyMetadata.cs

@@ -1,234 +1,216 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class CompanyMetadata: global::Jellyfin.Data.Entities.Metadata
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected CompanyMetadata(): base()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static CompanyMetadata CreateCompanyMetadataUnsafe()
-      {
-         return new CompanyMetadata();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_company0"></param>
-      public CompanyMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Company _company0)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
-
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
-
-         if (_company0 == null) throw new ArgumentNullException(nameof(_company0));
-         _company0.CompanyMetadata.Add(this);
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_company0"></param>
-      public static CompanyMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Company _company0)
-      {
-         return new CompanyMetadata(title, language, dateadded, datemodified, _company0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Description
-      /// </summary>
-      protected string _Description;
-      /// <summary>
-      /// When provided in a partial class, allows value of Description to be changed before setting.
-      /// </summary>
-      partial void SetDescription(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Description to be changed before returning.
-      /// </summary>
-      partial void GetDescription(ref string result);
-
-      /// <summary>
-      /// Max length = 65535
-      /// </summary>
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string Description
-      {
-         get
-         {
-            string value = _Description;
-            GetDescription(ref value);
-            return (_Description = value);
-         }
-         set
-         {
-            string oldValue = _Description;
-            SetDescription(oldValue, ref value);
-            if (oldValue != value)
+    public partial class CompanyMetadata : Metadata
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected CompanyMetadata()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static CompanyMetadata CreateCompanyMetadataUnsafe()
+        {
+            return new CompanyMetadata();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_company0"></param>
+        public CompanyMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Company _company0)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
+
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
+
+            if (_company0 == null) throw new ArgumentNullException(nameof(_company0));
+            _company0.CompanyMetadata.Add(this);
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_company0"></param>
+        public static CompanyMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Company _company0)
+        {
+            return new CompanyMetadata(title, language, dateadded, datemodified, _company0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Description
+        /// </summary>
+        protected string _Description;
+        /// <summary>
+        /// When provided in a partial class, allows value of Description to be changed before setting.
+        /// </summary>
+        partial void SetDescription(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Description to be changed before returning.
+        /// </summary>
+        partial void GetDescription(ref string result);
+
+        /// <summary>
+        /// Max length = 65535
+        /// </summary>
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string Description
+        {
+            get
+            {
+                string value = _Description;
+                GetDescription(ref value);
+                return (_Description = value);
+            }
+            set
+            {
+                string oldValue = _Description;
+                SetDescription(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Description = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Headquarters
+        /// </summary>
+        protected string _Headquarters;
+        /// <summary>
+        /// When provided in a partial class, allows value of Headquarters to be changed before setting.
+        /// </summary>
+        partial void SetHeadquarters(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Headquarters to be changed before returning.
+        /// </summary>
+        partial void GetHeadquarters(ref string result);
+
+        /// <summary>
+        /// Max length = 255
+        /// </summary>
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string Headquarters
+        {
+            get
+            {
+                string value = _Headquarters;
+                GetHeadquarters(ref value);
+                return (_Headquarters = value);
+            }
+            set
+            {
+                string oldValue = _Headquarters;
+                SetHeadquarters(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Headquarters = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Country
+        /// </summary>
+        protected string _Country;
+        /// <summary>
+        /// When provided in a partial class, allows value of Country to be changed before setting.
+        /// </summary>
+        partial void SetCountry(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Country to be changed before returning.
+        /// </summary>
+        partial void GetCountry(ref string result);
+
+        /// <summary>
+        /// Max length = 2
+        /// </summary>
+        [MaxLength(2)]
+        [StringLength(2)]
+        public string Country
+        {
+            get
             {
-               _Description = value;
+                string value = _Country;
+                GetCountry(ref value);
+                return (_Country = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Headquarters
-      /// </summary>
-      protected string _Headquarters;
-      /// <summary>
-      /// When provided in a partial class, allows value of Headquarters to be changed before setting.
-      /// </summary>
-      partial void SetHeadquarters(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Headquarters to be changed before returning.
-      /// </summary>
-      partial void GetHeadquarters(ref string result);
-
-      /// <summary>
-      /// Max length = 255
-      /// </summary>
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string Headquarters
-      {
-         get
-         {
-            string value = _Headquarters;
-            GetHeadquarters(ref value);
-            return (_Headquarters = value);
-         }
-         set
-         {
-            string oldValue = _Headquarters;
-            SetHeadquarters(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Headquarters = value;
+                string oldValue = _Country;
+                SetCountry(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Country = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Country
-      /// </summary>
-      protected string _Country;
-      /// <summary>
-      /// When provided in a partial class, allows value of Country to be changed before setting.
-      /// </summary>
-      partial void SetCountry(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Country to be changed before returning.
-      /// </summary>
-      partial void GetCountry(ref string result);
-
-      /// <summary>
-      /// Max length = 2
-      /// </summary>
-      [MaxLength(2)]
-      [StringLength(2)]
-      public string Country
-      {
-         get
-         {
-            string value = _Country;
-            GetCountry(ref value);
-            return (_Country = value);
-         }
-         set
-         {
-            string oldValue = _Country;
-            SetCountry(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Homepage
+        /// </summary>
+        protected string _Homepage;
+        /// <summary>
+        /// When provided in a partial class, allows value of Homepage to be changed before setting.
+        /// </summary>
+        partial void SetHomepage(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Homepage to be changed before returning.
+        /// </summary>
+        partial void GetHomepage(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Homepage
+        {
+            get
             {
-               _Country = value;
+                string value = _Homepage;
+                GetHomepage(ref value);
+                return (_Homepage = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Homepage
-      /// </summary>
-      protected string _Homepage;
-      /// <summary>
-      /// When provided in a partial class, allows value of Homepage to be changed before setting.
-      /// </summary>
-      partial void SetHomepage(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Homepage to be changed before returning.
-      /// </summary>
-      partial void GetHomepage(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Homepage
-      {
-         get
-         {
-            string value = _Homepage;
-            GetHomepage(ref value);
-            return (_Homepage = value);
-         }
-         set
-         {
-            string oldValue = _Homepage;
-            SetHomepage(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Homepage = value;
+                string oldValue = _Homepage;
+                SetHomepage(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Homepage = value;
+                }
             }
-         }
-      }
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 49 - 65
Jellyfin.Data/Entities/CustomItem.cs

@@ -1,84 +1,68 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class CustomItem: global::Jellyfin.Data.Entities.LibraryItem
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected CustomItem(): base()
-      {
-         CustomItemMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CustomItemMetadata>();
-         Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
+    public partial class CustomItem : LibraryItem
+    {
+        partial void Init();
 
-         Init();
-      }
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected CustomItem()
+        {
+            CustomItemMetadata = new HashSet<CustomItemMetadata>();
+            Releases = new HashSet<Release>();
 
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static CustomItem CreateCustomItemUnsafe()
-      {
-         return new CustomItem();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public CustomItem(Guid urlid, DateTime dateadded)
-      {
-         this.UrlId = urlid;
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static CustomItem CreateCustomItemUnsafe()
+        {
+            return new CustomItem();
+        }
 
-         this.CustomItemMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CustomItemMetadata>();
-         this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public CustomItem(Guid urlid, DateTime dateadded)
+        {
+            this.UrlId = urlid;
 
-         Init();
-      }
+            this.CustomItemMetadata = new HashSet<CustomItemMetadata>();
+            this.Releases = new HashSet<Release>();
 
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public static CustomItem Create(Guid urlid, DateTime dateadded)
-      {
-         return new CustomItem(urlid, dateadded);
-      }
+            Init();
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public static CustomItem Create(Guid urlid, DateTime dateadded)
+        {
+            return new CustomItem(urlid, dateadded);
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.CustomItemMetadata> CustomItemMetadata { get; protected set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("CustomItemMetadata_CustomItemMetadata_Id")]
+        public virtual ICollection<CustomItemMetadata> CustomItemMetadata { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
+        [ForeignKey("Release_Releases_Id")]
+        public virtual ICollection<Release> Releases { get; protected set; }
 
-   }
+    }
 }
 

+ 50 - 69
Jellyfin.Data/Entities/CustomItemMetadata.cs

@@ -1,86 +1,67 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class CustomItemMetadata: global::Jellyfin.Data.Entities.Metadata
-   {
-      partial void Init();
+    public partial class CustomItemMetadata : Metadata
+    {
+        partial void Init();
 
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected CustomItemMetadata(): base()
-      {
-         Init();
-      }
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected CustomItemMetadata()
+        {
+            Init();
+        }
 
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static CustomItemMetadata CreateCustomItemMetadataUnsafe()
-      {
-         return new CustomItemMetadata();
-      }
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static CustomItemMetadata CreateCustomItemMetadataUnsafe()
+        {
+            return new CustomItemMetadata();
+        }
 
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_customitem0"></param>
-      public CustomItemMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.CustomItem _customitem0)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_customitem0"></param>
+        public CustomItemMetadata(string title, string language, DateTime dateadded, DateTime datemodified, CustomItem _customitem0)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
 
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
 
-         if (_customitem0 == null) throw new ArgumentNullException(nameof(_customitem0));
-         _customitem0.CustomItemMetadata.Add(this);
+            if (_customitem0 == null) throw new ArgumentNullException(nameof(_customitem0));
+            _customitem0.CustomItemMetadata.Add(this);
 
 
-         Init();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_customitem0"></param>
-      public static CustomItemMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.CustomItem _customitem0)
-      {
-         return new CustomItemMetadata(title, language, dateadded, datemodified, _customitem0);
-      }
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_customitem0"></param>
+        public static CustomItemMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, CustomItem _customitem0)
+        {
+            return new CustomItemMetadata(title, language, dateadded, datemodified, _customitem0);
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 98 - 115
Jellyfin.Data/Entities/Episode.cs

@@ -1,127 +1,110 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Episode: global::Jellyfin.Data.Entities.LibraryItem
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Episode(): base()
-      {
-         // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
-         EpisodeMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.EpisodeMetadata>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Episode CreateEpisodeUnsafe()
-      {
-         return new Episode();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      /// <param name="_season0"></param>
-      public Episode(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Season _season0)
-      {
-         // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         this.UrlId = urlid;
-
-         if (_season0 == null) throw new ArgumentNullException(nameof(_season0));
-         _season0.Episodes.Add(this);
-
-         this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
-         this.EpisodeMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.EpisodeMetadata>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      /// <param name="_season0"></param>
-      public static Episode Create(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Season _season0)
-      {
-         return new Episode(urlid, dateadded, _season0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for EpisodeNumber
-      /// </summary>
-      protected int? _EpisodeNumber;
-      /// <summary>
-      /// When provided in a partial class, allows value of EpisodeNumber to be changed before setting.
-      /// </summary>
-      partial void SetEpisodeNumber(int? oldValue, ref int? newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of EpisodeNumber to be changed before returning.
-      /// </summary>
-      partial void GetEpisodeNumber(ref int? result);
-
-      public int? EpisodeNumber
-      {
-         get
-         {
-            int? value = _EpisodeNumber;
-            GetEpisodeNumber(ref value);
-            return (_EpisodeNumber = value);
-         }
-         set
-         {
-            int? oldValue = _EpisodeNumber;
-            SetEpisodeNumber(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Episode : LibraryItem
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Episode()
+        {
+            // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            Releases = new HashSet<Release>();
+            EpisodeMetadata = new HashSet<EpisodeMetadata>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Episode CreateEpisodeUnsafe()
+        {
+            return new Episode();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        /// <param name="_season0"></param>
+        public Episode(Guid urlid, DateTime dateadded, Season _season0)
+        {
+            // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            this.UrlId = urlid;
+
+            if (_season0 == null) throw new ArgumentNullException(nameof(_season0));
+            _season0.Episodes.Add(this);
+
+            this.Releases = new HashSet<Release>();
+            this.EpisodeMetadata = new HashSet<EpisodeMetadata>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        /// <param name="_season0"></param>
+        public static Episode Create(Guid urlid, DateTime dateadded, Season _season0)
+        {
+            return new Episode(urlid, dateadded, _season0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for EpisodeNumber
+        /// </summary>
+        protected int? _EpisodeNumber;
+        /// <summary>
+        /// When provided in a partial class, allows value of EpisodeNumber to be changed before setting.
+        /// </summary>
+        partial void SetEpisodeNumber(int? oldValue, ref int? newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of EpisodeNumber to be changed before returning.
+        /// </summary>
+        partial void GetEpisodeNumber(ref int? result);
+
+        public int? EpisodeNumber
+        {
+            get
             {
-               _EpisodeNumber = value;
+                int? value = _EpisodeNumber;
+                GetEpisodeNumber(ref value);
+                return (_EpisodeNumber = value);
             }
-         }
-      }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
+            set
+            {
+                int? oldValue = _EpisodeNumber;
+                SetEpisodeNumber(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _EpisodeNumber = value;
+                }
+            }
+        }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.EpisodeMetadata> EpisodeMetadata { get; protected set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("Release_Releases_Id")]
+        public virtual ICollection<Release> Releases { get; protected set; }
+        [ForeignKey("EpisodeMetadata_EpisodeMetadata_Id")]
+        public virtual ICollection<EpisodeMetadata> EpisodeMetadata { get; protected set; }
 
-   }
+    }
 }
 

+ 164 - 182
Jellyfin.Data/Entities/EpisodeMetadata.cs

@@ -1,197 +1,179 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class EpisodeMetadata: global::Jellyfin.Data.Entities.Metadata
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected EpisodeMetadata(): base()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static EpisodeMetadata CreateEpisodeMetadataUnsafe()
-      {
-         return new EpisodeMetadata();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_episode0"></param>
-      public EpisodeMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Episode _episode0)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
-
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
-
-         if (_episode0 == null) throw new ArgumentNullException(nameof(_episode0));
-         _episode0.EpisodeMetadata.Add(this);
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_episode0"></param>
-      public static EpisodeMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Episode _episode0)
-      {
-         return new EpisodeMetadata(title, language, dateadded, datemodified, _episode0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Outline
-      /// </summary>
-      protected string _Outline;
-      /// <summary>
-      /// When provided in a partial class, allows value of Outline to be changed before setting.
-      /// </summary>
-      partial void SetOutline(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Outline to be changed before returning.
-      /// </summary>
-      partial void GetOutline(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Outline
-      {
-         get
-         {
-            string value = _Outline;
-            GetOutline(ref value);
-            return (_Outline = value);
-         }
-         set
-         {
-            string oldValue = _Outline;
-            SetOutline(oldValue, ref value);
-            if (oldValue != value)
+    public partial class EpisodeMetadata : Metadata
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected EpisodeMetadata()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static EpisodeMetadata CreateEpisodeMetadataUnsafe()
+        {
+            return new EpisodeMetadata();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_episode0"></param>
+        public EpisodeMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Episode _episode0)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
+
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
+
+            if (_episode0 == null) throw new ArgumentNullException(nameof(_episode0));
+            _episode0.EpisodeMetadata.Add(this);
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_episode0"></param>
+        public static EpisodeMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Episode _episode0)
+        {
+            return new EpisodeMetadata(title, language, dateadded, datemodified, _episode0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Outline
+        /// </summary>
+        protected string _Outline;
+        /// <summary>
+        /// When provided in a partial class, allows value of Outline to be changed before setting.
+        /// </summary>
+        partial void SetOutline(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Outline to be changed before returning.
+        /// </summary>
+        partial void GetOutline(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Outline
+        {
+            get
+            {
+                string value = _Outline;
+                GetOutline(ref value);
+                return (_Outline = value);
+            }
+            set
+            {
+                string oldValue = _Outline;
+                SetOutline(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Outline = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Plot
+        /// </summary>
+        protected string _Plot;
+        /// <summary>
+        /// When provided in a partial class, allows value of Plot to be changed before setting.
+        /// </summary>
+        partial void SetPlot(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Plot to be changed before returning.
+        /// </summary>
+        partial void GetPlot(ref string result);
+
+        /// <summary>
+        /// Max length = 65535
+        /// </summary>
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string Plot
+        {
+            get
+            {
+                string value = _Plot;
+                GetPlot(ref value);
+                return (_Plot = value);
+            }
+            set
             {
-               _Outline = value;
+                string oldValue = _Plot;
+                SetPlot(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Plot = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Plot
-      /// </summary>
-      protected string _Plot;
-      /// <summary>
-      /// When provided in a partial class, allows value of Plot to be changed before setting.
-      /// </summary>
-      partial void SetPlot(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Plot to be changed before returning.
-      /// </summary>
-      partial void GetPlot(ref string result);
-
-      /// <summary>
-      /// Max length = 65535
-      /// </summary>
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string Plot
-      {
-         get
-         {
-            string value = _Plot;
-            GetPlot(ref value);
-            return (_Plot = value);
-         }
-         set
-         {
-            string oldValue = _Plot;
-            SetPlot(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Tagline
+        /// </summary>
+        protected string _Tagline;
+        /// <summary>
+        /// When provided in a partial class, allows value of Tagline to be changed before setting.
+        /// </summary>
+        partial void SetTagline(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Tagline to be changed before returning.
+        /// </summary>
+        partial void GetTagline(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Tagline
+        {
+            get
             {
-               _Plot = value;
+                string value = _Tagline;
+                GetTagline(ref value);
+                return (_Tagline = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Tagline
-      /// </summary>
-      protected string _Tagline;
-      /// <summary>
-      /// When provided in a partial class, allows value of Tagline to be changed before setting.
-      /// </summary>
-      partial void SetTagline(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Tagline to be changed before returning.
-      /// </summary>
-      partial void GetTagline(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Tagline
-      {
-         get
-         {
-            string value = _Tagline;
-            GetTagline(ref value);
-            return (_Tagline = value);
-         }
-         set
-         {
-            string oldValue = _Tagline;
-            SetTagline(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Tagline = value;
+                string oldValue = _Tagline;
+                SetTagline(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Tagline = value;
+                }
             }
-         }
-      }
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 137 - 148
Jellyfin.Data/Entities/Genre.cs

@@ -1,163 +1,152 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Genre
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Genre()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Genre CreateGenreUnsafe()
-      {
-         return new Genre();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="name"></param>
-      /// <param name="_metadata0"></param>
-      public Genre(string name, global::Jellyfin.Data.Entities.Metadata _metadata0)
-      {
-         if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
-         this.Name = name;
-
-         if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
-         _metadata0.Genres.Add(this);
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="name"></param>
-      /// <param name="_metadata0"></param>
-      public static Genre Create(string name, global::Jellyfin.Data.Entities.Metadata _metadata0)
-      {
-         return new Genre(name, _metadata0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Genre
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Genre()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Genre CreateGenreUnsafe()
+        {
+            return new Genre();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="_metadata0"></param>
+        public Genre(string name, Metadata _metadata0)
+        {
+            if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
+            this.Name = name;
+
+            if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
+            _metadata0.Genres.Add(this);
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="_metadata0"></param>
+        public static Genre Create(string name, Metadata _metadata0)
+        {
+            return new Genre(name, _metadata0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
             {
-               _Id = value;
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Name
-      /// </summary>
-      internal string _Name;
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before setting.
-      /// </summary>
-      partial void SetName(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before returning.
-      /// </summary>
-      partial void GetName(ref string result);
-
-      /// <summary>
-      /// Indexed, Required, Max length = 255
-      /// </summary>
-      [Required]
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string Name
-      {
-         get
-         {
-            string value = _Name;
-            GetName(ref value);
-            return (_Name = value);
-         }
-         set
-         {
-            string oldValue = _Name;
-            SetName(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Name
+        /// </summary>
+        internal string _Name;
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before setting.
+        /// </summary>
+        partial void SetName(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before returning.
+        /// </summary>
+        partial void GetName(ref string result);
+
+        /// <summary>
+        /// Indexed, Required, Max length = 255
+        /// </summary>
+        [Required]
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string Name
+        {
+            get
             {
-               _Name = value;
+                string value = _Name;
+                GetName(ref value);
+                return (_Name = value);
             }
-         }
-      }
+            set
+            {
+                string oldValue = _Name;
+                SetName(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Name = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 100 - 106
Jellyfin.Data/Entities/Group.cs

@@ -1,115 +1,109 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Group
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Group()
-      {
-         GroupPermissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>();
-         ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>();
-         Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Group CreateGroupUnsafe()
-      {
-         return new Group();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="name"></param>
-      /// <param name="_user0"></param>
-      public Group(string name, global::Jellyfin.Data.Entities.User _user0)
-      {
-         if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
-         this.Name = name;
-
-         if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
-         _user0.Groups.Add(this);
-
-         this.GroupPermissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>();
-         this.ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>();
-         this.Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="name"></param>
-      /// <param name="_user0"></param>
-      public static Group Create(string name, global::Jellyfin.Data.Entities.User _user0)
-      {
-         return new Group(name, _user0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id { get; protected set; }
-
-      /// <summary>
-      /// Required, Max length = 255
-      /// </summary>
-      [Required]
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string Name { get; set; }
-
-      /// <summary>
-      /// Concurrency token
-      /// </summary>
-      [Timestamp]
-      public Byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.Permission> GroupPermissions { get; protected set; }
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.ProviderMapping> ProviderMappings { get; protected set; }
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.Preference> Preferences { get; protected set; }
-
-   }
+    public partial class Group
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Group()
+        {
+            GroupPermissions = new HashSet<Permission>();
+            ProviderMappings = new HashSet<ProviderMapping>();
+            Preferences = new HashSet<Preference>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Group CreateGroupUnsafe()
+        {
+            return new Group();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="_user0"></param>
+        public Group(string name, User _user0)
+        {
+            if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
+            this.Name = name;
+
+            if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
+            _user0.Groups.Add(this);
+
+            this.GroupPermissions = new HashSet<Permission>();
+            this.ProviderMappings = new HashSet<ProviderMapping>();
+            this.Preferences = new HashSet<Preference>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="_user0"></param>
+        public static Group Create(string name, User _user0)
+        {
+            return new Group(name, _user0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id { get; protected set; }
+
+        /// <summary>
+        /// Required, Max length = 255
+        /// </summary>
+        [Required]
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+
+        [ForeignKey("Permission_GroupPermissions_Id")]
+        public virtual ICollection<Permission> GroupPermissions { get; protected set; }
+
+        [ForeignKey("ProviderMapping_ProviderMappings_Id")]
+        public virtual ICollection<ProviderMapping> ProviderMappings { get; protected set; }
+
+        [ForeignKey("Preference_Preferences_Id")]
+        public virtual ICollection<Preference> Preferences { get; protected set; }
+
+    }
 }
 

+ 132 - 143
Jellyfin.Data/Entities/Library.cs

@@ -1,158 +1,147 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Library
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Library()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Library CreateLibraryUnsafe()
-      {
-         return new Library();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="name"></param>
-      public Library(string name)
-      {
-         if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
-         this.Name = name;
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="name"></param>
-      public static Library Create(string name)
-      {
-         return new Library(name);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Library
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Library()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Library CreateLibraryUnsafe()
+        {
+            return new Library();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="name"></param>
+        public Library(string name)
+        {
+            if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
+            this.Name = name;
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="name"></param>
+        public static Library Create(string name)
+        {
+            return new Library(name);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
             {
-               _Id = value;
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Name
-      /// </summary>
-      protected string _Name;
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before setting.
-      /// </summary>
-      partial void SetName(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before returning.
-      /// </summary>
-      partial void GetName(ref string result);
-
-      /// <summary>
-      /// Required, Max length = 1024
-      /// </summary>
-      [Required]
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Name
-      {
-         get
-         {
-            string value = _Name;
-            GetName(ref value);
-            return (_Name = value);
-         }
-         set
-         {
-            string oldValue = _Name;
-            SetName(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Name
+        /// </summary>
+        protected string _Name;
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before setting.
+        /// </summary>
+        partial void SetName(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before returning.
+        /// </summary>
+        partial void GetName(ref string result);
+
+        /// <summary>
+        /// Required, Max length = 1024
+        /// </summary>
+        [Required]
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Name
+        {
+            get
             {
-               _Name = value;
+                string value = _Name;
+                GetName(ref value);
+                return (_Name = value);
             }
-         }
-      }
+            set
+            {
+                string oldValue = _Name;
+                SetName(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Name = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 156 - 166
Jellyfin.Data/Entities/LibraryItem.cs

@@ -1,180 +1,170 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public abstract partial class LibraryItem
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to being abstract.
-      /// </summary>
-      protected LibraryItem()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      protected LibraryItem(Guid urlid, DateTime dateadded)
-      {
-         this.UrlId = urlid;
-
-
-         Init();
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public abstract partial class LibraryItem
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to being abstract.
+        /// </summary>
+        protected LibraryItem()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        protected LibraryItem(Guid urlid, DateTime dateadded)
+        {
+            this.UrlId = urlid;
+
+
+            Init();
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
+            {
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for UrlId
+        /// </summary>
+        internal Guid _UrlId;
+        /// <summary>
+        /// When provided in a partial class, allows value of UrlId to be changed before setting.
+        /// </summary>
+        partial void SetUrlId(Guid oldValue, ref Guid newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of UrlId to be changed before returning.
+        /// </summary>
+        partial void GetUrlId(ref Guid result);
+
+        /// <summary>
+        /// Indexed, Required
+        /// This is whats gets displayed in the Urls and API requests. This could also be a string.
+        /// </summary>
+        [Required]
+        public Guid UrlId
+        {
+            get
+            {
+                Guid value = _UrlId;
+                GetUrlId(ref value);
+                return (_UrlId = value);
+            }
+            set
             {
-               _Id = value;
+                Guid oldValue = _UrlId;
+                SetUrlId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _UrlId = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for UrlId
-      /// </summary>
-      internal Guid _UrlId;
-      /// <summary>
-      /// When provided in a partial class, allows value of UrlId to be changed before setting.
-      /// </summary>
-      partial void SetUrlId(Guid oldValue, ref Guid newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of UrlId to be changed before returning.
-      /// </summary>
-      partial void GetUrlId(ref Guid result);
-
-      /// <summary>
-      /// Indexed, Required
-      /// This is whats gets displayed in the Urls and API requests. This could also be a string.
-      /// </summary>
-      [Required]
-      public Guid UrlId
-      {
-         get
-         {
-            Guid value = _UrlId;
-            GetUrlId(ref value);
-            return (_UrlId = value);
-         }
-         set
-         {
-            Guid oldValue = _UrlId;
-            SetUrlId(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for DateAdded
+        /// </summary>
+        protected DateTime _DateAdded;
+        /// <summary>
+        /// When provided in a partial class, allows value of DateAdded to be changed before setting.
+        /// </summary>
+        partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of DateAdded to be changed before returning.
+        /// </summary>
+        partial void GetDateAdded(ref DateTime result);
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public DateTime DateAdded
+        {
+            get
             {
-               _UrlId = value;
+                DateTime value = _DateAdded;
+                GetDateAdded(ref value);
+                return (_DateAdded = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for DateAdded
-      /// </summary>
-      protected DateTime _DateAdded;
-      /// <summary>
-      /// When provided in a partial class, allows value of DateAdded to be changed before setting.
-      /// </summary>
-      partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of DateAdded to be changed before returning.
-      /// </summary>
-      partial void GetDateAdded(ref DateTime result);
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public DateTime DateAdded
-      {
-         get
-         {
-            DateTime value = _DateAdded;
-            GetDateAdded(ref value);
-            return (_DateAdded = value);
-         }
-         internal set
-         {
-            DateTime oldValue = _DateAdded;
-            SetDateAdded(oldValue, ref value);
-            if (oldValue != value)
+            internal set
             {
-               _DateAdded = value;
+                DateTime oldValue = _DateAdded;
+                SetDateAdded(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _DateAdded = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      public virtual global::Jellyfin.Data.Entities.LibraryRoot LibraryRoot { get; set; }
-
-   }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [ForeignKey("LibraryRoot_Id")]
+        public virtual LibraryRoot LibraryRoot { get; set; }
+
+    }
 }
 

+ 178 - 188
Jellyfin.Data/Entities/LibraryRoot.cs

@@ -1,202 +1,192 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class LibraryRoot
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected LibraryRoot()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static LibraryRoot CreateLibraryRootUnsafe()
-      {
-         return new LibraryRoot();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="path">Absolute Path</param>
-      public LibraryRoot(string path)
-      {
-         if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
-         this.Path = path;
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="path">Absolute Path</param>
-      public static LibraryRoot Create(string path)
-      {
-         return new LibraryRoot(path);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class LibraryRoot
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected LibraryRoot()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static LibraryRoot CreateLibraryRootUnsafe()
+        {
+            return new LibraryRoot();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="path">Absolute Path</param>
+        public LibraryRoot(string path)
+        {
+            if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
+            this.Path = path;
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="path">Absolute Path</param>
+        public static LibraryRoot Create(string path)
+        {
+            return new LibraryRoot(path);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
+            {
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Path
+        /// </summary>
+        protected string _Path;
+        /// <summary>
+        /// When provided in a partial class, allows value of Path to be changed before setting.
+        /// </summary>
+        partial void SetPath(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Path to be changed before returning.
+        /// </summary>
+        partial void GetPath(ref string result);
+
+        /// <summary>
+        /// Required, Max length = 65535
+        /// Absolute Path
+        /// </summary>
+        [Required]
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string Path
+        {
+            get
+            {
+                string value = _Path;
+                GetPath(ref value);
+                return (_Path = value);
+            }
+            set
             {
-               _Id = value;
+                string oldValue = _Path;
+                SetPath(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Path = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Path
-      /// </summary>
-      protected string _Path;
-      /// <summary>
-      /// When provided in a partial class, allows value of Path to be changed before setting.
-      /// </summary>
-      partial void SetPath(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Path to be changed before returning.
-      /// </summary>
-      partial void GetPath(ref string result);
-
-      /// <summary>
-      /// Required, Max length = 65535
-      /// Absolute Path
-      /// </summary>
-      [Required]
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string Path
-      {
-         get
-         {
-            string value = _Path;
-            GetPath(ref value);
-            return (_Path = value);
-         }
-         set
-         {
-            string oldValue = _Path;
-            SetPath(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for NetworkPath
+        /// </summary>
+        protected string _NetworkPath;
+        /// <summary>
+        /// When provided in a partial class, allows value of NetworkPath to be changed before setting.
+        /// </summary>
+        partial void SetNetworkPath(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of NetworkPath to be changed before returning.
+        /// </summary>
+        partial void GetNetworkPath(ref string result);
+
+        /// <summary>
+        /// Max length = 65535
+        /// Absolute network path, for example for transcoding sattelites.
+        /// </summary>
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string NetworkPath
+        {
+            get
             {
-               _Path = value;
+                string value = _NetworkPath;
+                GetNetworkPath(ref value);
+                return (_NetworkPath = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for NetworkPath
-      /// </summary>
-      protected string _NetworkPath;
-      /// <summary>
-      /// When provided in a partial class, allows value of NetworkPath to be changed before setting.
-      /// </summary>
-      partial void SetNetworkPath(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of NetworkPath to be changed before returning.
-      /// </summary>
-      partial void GetNetworkPath(ref string result);
-
-      /// <summary>
-      /// Max length = 65535
-      /// Absolute network path, for example for transcoding sattelites.
-      /// </summary>
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string NetworkPath
-      {
-         get
-         {
-            string value = _NetworkPath;
-            GetNetworkPath(ref value);
-            return (_NetworkPath = value);
-         }
-         set
-         {
-            string oldValue = _NetworkPath;
-            SetNetworkPath(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _NetworkPath = value;
+                string oldValue = _NetworkPath;
+                SetNetworkPath(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _NetworkPath = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      public virtual global::Jellyfin.Data.Entities.Library Library { get; set; }
-
-   }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [ForeignKey("Library_Id")]
+        public virtual Library Library { get; set; }
+
+    }
 }
 

+ 181 - 190
Jellyfin.Data/Entities/MediaFile.cs

@@ -1,209 +1,200 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class MediaFile
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected MediaFile()
-      {
-         MediaFileStreams = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFileStream>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static MediaFile CreateMediaFileUnsafe()
-      {
-         return new MediaFile();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="path">Relative to the LibraryRoot</param>
-      /// <param name="kind"></param>
-      /// <param name="_release0"></param>
-      public MediaFile(string path, global::Jellyfin.Data.Enums.MediaFileKind kind, global::Jellyfin.Data.Entities.Release _release0)
-      {
-         if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
-         this.Path = path;
-
-         this.Kind = kind;
-
-         if (_release0 == null) throw new ArgumentNullException(nameof(_release0));
-         _release0.MediaFiles.Add(this);
-
-         this.MediaFileStreams = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFileStream>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="path">Relative to the LibraryRoot</param>
-      /// <param name="kind"></param>
-      /// <param name="_release0"></param>
-      public static MediaFile Create(string path, global::Jellyfin.Data.Enums.MediaFileKind kind, global::Jellyfin.Data.Entities.Release _release0)
-      {
-         return new MediaFile(path, kind, _release0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class MediaFile
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected MediaFile()
+        {
+            MediaFileStreams = new HashSet<MediaFileStream>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static MediaFile CreateMediaFileUnsafe()
+        {
+            return new MediaFile();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="path">Relative to the LibraryRoot</param>
+        /// <param name="kind"></param>
+        /// <param name="_release0"></param>
+        public MediaFile(string path, Enums.MediaFileKind kind, Release _release0)
+        {
+            if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
+            this.Path = path;
+
+            this.Kind = kind;
+
+            if (_release0 == null) throw new ArgumentNullException(nameof(_release0));
+            _release0.MediaFiles.Add(this);
+
+            this.MediaFileStreams = new HashSet<MediaFileStream>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="path">Relative to the LibraryRoot</param>
+        /// <param name="kind"></param>
+        /// <param name="_release0"></param>
+        public static MediaFile Create(string path, Enums.MediaFileKind kind, Release _release0)
+        {
+            return new MediaFile(path, kind, _release0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
+            {
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Path
+        /// </summary>
+        protected string _Path;
+        /// <summary>
+        /// When provided in a partial class, allows value of Path to be changed before setting.
+        /// </summary>
+        partial void SetPath(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Path to be changed before returning.
+        /// </summary>
+        partial void GetPath(ref string result);
+
+        /// <summary>
+        /// Required, Max length = 65535
+        /// Relative to the LibraryRoot
+        /// </summary>
+        [Required]
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string Path
+        {
+            get
+            {
+                string value = _Path;
+                GetPath(ref value);
+                return (_Path = value);
+            }
+            set
             {
-               _Id = value;
+                string oldValue = _Path;
+                SetPath(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Path = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Path
-      /// </summary>
-      protected string _Path;
-      /// <summary>
-      /// When provided in a partial class, allows value of Path to be changed before setting.
-      /// </summary>
-      partial void SetPath(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Path to be changed before returning.
-      /// </summary>
-      partial void GetPath(ref string result);
-
-      /// <summary>
-      /// Required, Max length = 65535
-      /// Relative to the LibraryRoot
-      /// </summary>
-      [Required]
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string Path
-      {
-         get
-         {
-            string value = _Path;
-            GetPath(ref value);
-            return (_Path = value);
-         }
-         set
-         {
-            string oldValue = _Path;
-            SetPath(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Kind
+        /// </summary>
+        protected Enums.MediaFileKind _Kind;
+        /// <summary>
+        /// When provided in a partial class, allows value of Kind to be changed before setting.
+        /// </summary>
+        partial void SetKind(Enums.MediaFileKind oldValue, ref Enums.MediaFileKind newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Kind to be changed before returning.
+        /// </summary>
+        partial void GetKind(ref Enums.MediaFileKind result);
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public Enums.MediaFileKind Kind
+        {
+            get
             {
-               _Path = value;
+                Enums.MediaFileKind value = _Kind;
+                GetKind(ref value);
+                return (_Kind = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Kind
-      /// </summary>
-      protected global::Jellyfin.Data.Enums.MediaFileKind _Kind;
-      /// <summary>
-      /// When provided in a partial class, allows value of Kind to be changed before setting.
-      /// </summary>
-      partial void SetKind(global::Jellyfin.Data.Enums.MediaFileKind oldValue, ref global::Jellyfin.Data.Enums.MediaFileKind newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Kind to be changed before returning.
-      /// </summary>
-      partial void GetKind(ref global::Jellyfin.Data.Enums.MediaFileKind result);
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public global::Jellyfin.Data.Enums.MediaFileKind Kind
-      {
-         get
-         {
-            global::Jellyfin.Data.Enums.MediaFileKind value = _Kind;
-            GetKind(ref value);
-            return (_Kind = value);
-         }
-         set
-         {
-            global::Jellyfin.Data.Enums.MediaFileKind oldValue = _Kind;
-            SetKind(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Kind = value;
+                Enums.MediaFileKind oldValue = _Kind;
+                SetKind(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Kind = value;
+                }
             }
-         }
-      }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.MediaFileStream> MediaFileStreams { get; protected set; }
+        [ForeignKey("MediaFileStream_MediaFileStreams_Id")]
+        public virtual ICollection<MediaFileStream> MediaFileStreams { get; protected set; }
 
-   }
+    }
 }
 

+ 134 - 145
Jellyfin.Data/Entities/MediaFileStream.cs

@@ -1,160 +1,149 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class MediaFileStream
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected MediaFileStream()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static MediaFileStream CreateMediaFileStreamUnsafe()
-      {
-         return new MediaFileStream();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="streamnumber"></param>
-      /// <param name="_mediafile0"></param>
-      public MediaFileStream(int streamnumber, global::Jellyfin.Data.Entities.MediaFile _mediafile0)
-      {
-         this.StreamNumber = streamnumber;
-
-         if (_mediafile0 == null) throw new ArgumentNullException(nameof(_mediafile0));
-         _mediafile0.MediaFileStreams.Add(this);
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="streamnumber"></param>
-      /// <param name="_mediafile0"></param>
-      public static MediaFileStream Create(int streamnumber, global::Jellyfin.Data.Entities.MediaFile _mediafile0)
-      {
-         return new MediaFileStream(streamnumber, _mediafile0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class MediaFileStream
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected MediaFileStream()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static MediaFileStream CreateMediaFileStreamUnsafe()
+        {
+            return new MediaFileStream();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="streamnumber"></param>
+        /// <param name="_mediafile0"></param>
+        public MediaFileStream(int streamnumber, MediaFile _mediafile0)
+        {
+            this.StreamNumber = streamnumber;
+
+            if (_mediafile0 == null) throw new ArgumentNullException(nameof(_mediafile0));
+            _mediafile0.MediaFileStreams.Add(this);
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="streamnumber"></param>
+        /// <param name="_mediafile0"></param>
+        public static MediaFileStream Create(int streamnumber, MediaFile _mediafile0)
+        {
+            return new MediaFileStream(streamnumber, _mediafile0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
             {
-               _Id = value;
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for StreamNumber
-      /// </summary>
-      protected int _StreamNumber;
-      /// <summary>
-      /// When provided in a partial class, allows value of StreamNumber to be changed before setting.
-      /// </summary>
-      partial void SetStreamNumber(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of StreamNumber to be changed before returning.
-      /// </summary>
-      partial void GetStreamNumber(ref int result);
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public int StreamNumber
-      {
-         get
-         {
-            int value = _StreamNumber;
-            GetStreamNumber(ref value);
-            return (_StreamNumber = value);
-         }
-         set
-         {
-            int oldValue = _StreamNumber;
-            SetStreamNumber(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for StreamNumber
+        /// </summary>
+        protected int _StreamNumber;
+        /// <summary>
+        /// When provided in a partial class, allows value of StreamNumber to be changed before setting.
+        /// </summary>
+        partial void SetStreamNumber(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of StreamNumber to be changed before returning.
+        /// </summary>
+        partial void GetStreamNumber(ref int result);
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public int StreamNumber
+        {
+            get
             {
-               _StreamNumber = value;
+                int value = _StreamNumber;
+                GetStreamNumber(ref value);
+                return (_StreamNumber = value);
             }
-         }
-      }
+            set
+            {
+                int oldValue = _StreamNumber;
+                SetStreamNumber(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _StreamNumber = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 347 - 352
Jellyfin.Data/Entities/Metadata.cs

@@ -1,385 +1,380 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public abstract partial class Metadata
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to being abstract.
-      /// </summary>
-      protected Metadata()
-      {
-         PersonRoles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PersonRole>();
-         Genres = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Genre>();
-         Artwork = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Artwork>();
-         Ratings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Rating>();
-         Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      protected Metadata(string title, string language, DateTime dateadded, DateTime datemodified)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
-
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
-
-         this.PersonRoles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PersonRole>();
-         this.Genres = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Genre>();
-         this.Artwork = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Artwork>();
-         this.Ratings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Rating>();
-         this.Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
-
-         Init();
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public abstract partial class Metadata
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to being abstract.
+        /// </summary>
+        protected Metadata()
+        {
+            PersonRoles = new HashSet<PersonRole>();
+            Genres = new HashSet<Genre>();
+            Artwork = new HashSet<Artwork>();
+            Ratings = new HashSet<Rating>();
+            Sources = new HashSet<MetadataProviderId>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        protected Metadata(string title, string language, DateTime dateadded, DateTime datemodified)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
+
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
+
+            this.PersonRoles = new HashSet<PersonRole>();
+            this.Genres = new HashSet<Genre>();
+            this.Artwork = new HashSet<Artwork>();
+            this.Ratings = new HashSet<Rating>();
+            this.Sources = new HashSet<MetadataProviderId>();
+
+            Init();
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
+            {
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Title
+        /// </summary>
+        protected string _Title;
+        /// <summary>
+        /// When provided in a partial class, allows value of Title to be changed before setting.
+        /// </summary>
+        partial void SetTitle(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Title to be changed before returning.
+        /// </summary>
+        partial void GetTitle(ref string result);
+
+        /// <summary>
+        /// Required, Max length = 1024
+        /// The title or name of the object
+        /// </summary>
+        [Required]
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Title
+        {
+            get
+            {
+                string value = _Title;
+                GetTitle(ref value);
+                return (_Title = value);
+            }
+            set
+            {
+                string oldValue = _Title;
+                SetTitle(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Title = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for OriginalTitle
+        /// </summary>
+        protected string _OriginalTitle;
+        /// <summary>
+        /// When provided in a partial class, allows value of OriginalTitle to be changed before setting.
+        /// </summary>
+        partial void SetOriginalTitle(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of OriginalTitle to be changed before returning.
+        /// </summary>
+        partial void GetOriginalTitle(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string OriginalTitle
+        {
+            get
             {
-               _Id = value;
+                string value = _OriginalTitle;
+                GetOriginalTitle(ref value);
+                return (_OriginalTitle = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Title
-      /// </summary>
-      protected string _Title;
-      /// <summary>
-      /// When provided in a partial class, allows value of Title to be changed before setting.
-      /// </summary>
-      partial void SetTitle(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Title to be changed before returning.
-      /// </summary>
-      partial void GetTitle(ref string result);
-
-      /// <summary>
-      /// Required, Max length = 1024
-      /// The title or name of the object
-      /// </summary>
-      [Required]
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Title
-      {
-         get
-         {
-            string value = _Title;
-            GetTitle(ref value);
-            return (_Title = value);
-         }
-         set
-         {
-            string oldValue = _Title;
-            SetTitle(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Title = value;
+                string oldValue = _OriginalTitle;
+                SetOriginalTitle(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _OriginalTitle = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for OriginalTitle
-      /// </summary>
-      protected string _OriginalTitle;
-      /// <summary>
-      /// When provided in a partial class, allows value of OriginalTitle to be changed before setting.
-      /// </summary>
-      partial void SetOriginalTitle(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of OriginalTitle to be changed before returning.
-      /// </summary>
-      partial void GetOriginalTitle(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string OriginalTitle
-      {
-         get
-         {
-            string value = _OriginalTitle;
-            GetOriginalTitle(ref value);
-            return (_OriginalTitle = value);
-         }
-         set
-         {
-            string oldValue = _OriginalTitle;
-            SetOriginalTitle(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for SortTitle
+        /// </summary>
+        protected string _SortTitle;
+        /// <summary>
+        /// When provided in a partial class, allows value of SortTitle to be changed before setting.
+        /// </summary>
+        partial void SetSortTitle(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of SortTitle to be changed before returning.
+        /// </summary>
+        partial void GetSortTitle(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string SortTitle
+        {
+            get
             {
-               _OriginalTitle = value;
+                string value = _SortTitle;
+                GetSortTitle(ref value);
+                return (_SortTitle = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for SortTitle
-      /// </summary>
-      protected string _SortTitle;
-      /// <summary>
-      /// When provided in a partial class, allows value of SortTitle to be changed before setting.
-      /// </summary>
-      partial void SetSortTitle(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of SortTitle to be changed before returning.
-      /// </summary>
-      partial void GetSortTitle(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string SortTitle
-      {
-         get
-         {
-            string value = _SortTitle;
-            GetSortTitle(ref value);
-            return (_SortTitle = value);
-         }
-         set
-         {
-            string oldValue = _SortTitle;
-            SetSortTitle(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _SortTitle = value;
+                string oldValue = _SortTitle;
+                SetSortTitle(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _SortTitle = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Language
-      /// </summary>
-      protected string _Language;
-      /// <summary>
-      /// When provided in a partial class, allows value of Language to be changed before setting.
-      /// </summary>
-      partial void SetLanguage(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Language to be changed before returning.
-      /// </summary>
-      partial void GetLanguage(ref string result);
-
-      /// <summary>
-      /// Required, Min length = 3, Max length = 3
-      /// ISO-639-3 3-character language codes
-      /// </summary>
-      [Required]
-      [MinLength(3)]
-      [MaxLength(3)]
-      [StringLength(3)]
-      public string Language
-      {
-         get
-         {
-            string value = _Language;
-            GetLanguage(ref value);
-            return (_Language = value);
-         }
-         set
-         {
-            string oldValue = _Language;
-            SetLanguage(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Language
+        /// </summary>
+        protected string _Language;
+        /// <summary>
+        /// When provided in a partial class, allows value of Language to be changed before setting.
+        /// </summary>
+        partial void SetLanguage(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Language to be changed before returning.
+        /// </summary>
+        partial void GetLanguage(ref string result);
+
+        /// <summary>
+        /// Required, Min length = 3, Max length = 3
+        /// ISO-639-3 3-character language codes
+        /// </summary>
+        [Required]
+        [MinLength(3)]
+        [MaxLength(3)]
+        [StringLength(3)]
+        public string Language
+        {
+            get
             {
-               _Language = value;
+                string value = _Language;
+                GetLanguage(ref value);
+                return (_Language = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for ReleaseDate
-      /// </summary>
-      protected DateTimeOffset? _ReleaseDate;
-      /// <summary>
-      /// When provided in a partial class, allows value of ReleaseDate to be changed before setting.
-      /// </summary>
-      partial void SetReleaseDate(DateTimeOffset? oldValue, ref DateTimeOffset? newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of ReleaseDate to be changed before returning.
-      /// </summary>
-      partial void GetReleaseDate(ref DateTimeOffset? result);
-
-      public DateTimeOffset? ReleaseDate
-      {
-         get
-         {
-            DateTimeOffset? value = _ReleaseDate;
-            GetReleaseDate(ref value);
-            return (_ReleaseDate = value);
-         }
-         set
-         {
-            DateTimeOffset? oldValue = _ReleaseDate;
-            SetReleaseDate(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _ReleaseDate = value;
+                string oldValue = _Language;
+                SetLanguage(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Language = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for DateAdded
-      /// </summary>
-      protected DateTime _DateAdded;
-      /// <summary>
-      /// When provided in a partial class, allows value of DateAdded to be changed before setting.
-      /// </summary>
-      partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of DateAdded to be changed before returning.
-      /// </summary>
-      partial void GetDateAdded(ref DateTime result);
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public DateTime DateAdded
-      {
-         get
-         {
-            DateTime value = _DateAdded;
-            GetDateAdded(ref value);
-            return (_DateAdded = value);
-         }
-         internal set
-         {
-            DateTime oldValue = _DateAdded;
-            SetDateAdded(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for ReleaseDate
+        /// </summary>
+        protected DateTimeOffset? _ReleaseDate;
+        /// <summary>
+        /// When provided in a partial class, allows value of ReleaseDate to be changed before setting.
+        /// </summary>
+        partial void SetReleaseDate(DateTimeOffset? oldValue, ref DateTimeOffset? newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of ReleaseDate to be changed before returning.
+        /// </summary>
+        partial void GetReleaseDate(ref DateTimeOffset? result);
+
+        public DateTimeOffset? ReleaseDate
+        {
+            get
             {
-               _DateAdded = value;
+                DateTimeOffset? value = _ReleaseDate;
+                GetReleaseDate(ref value);
+                return (_ReleaseDate = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for DateModified
-      /// </summary>
-      protected DateTime _DateModified;
-      /// <summary>
-      /// When provided in a partial class, allows value of DateModified to be changed before setting.
-      /// </summary>
-      partial void SetDateModified(DateTime oldValue, ref DateTime newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of DateModified to be changed before returning.
-      /// </summary>
-      partial void GetDateModified(ref DateTime result);
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public DateTime DateModified
-      {
-         get
-         {
-            DateTime value = _DateModified;
-            GetDateModified(ref value);
-            return (_DateModified = value);
-         }
-         internal set
-         {
-            DateTime oldValue = _DateModified;
-            SetDateModified(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _DateModified = value;
+                DateTimeOffset? oldValue = _ReleaseDate;
+                SetReleaseDate(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _ReleaseDate = value;
+                }
             }
-         }
-      }
+        }
+
+        /// <summary>
+        /// Backing field for DateAdded
+        /// </summary>
+        protected DateTime _DateAdded;
+        /// <summary>
+        /// When provided in a partial class, allows value of DateAdded to be changed before setting.
+        /// </summary>
+        partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of DateAdded to be changed before returning.
+        /// </summary>
+        partial void GetDateAdded(ref DateTime result);
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public DateTime DateAdded
+        {
+            get
+            {
+                DateTime value = _DateAdded;
+                GetDateAdded(ref value);
+                return (_DateAdded = value);
+            }
+            internal set
+            {
+                DateTime oldValue = _DateAdded;
+                SetDateAdded(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _DateAdded = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for DateModified
+        /// </summary>
+        protected DateTime _DateModified;
+        /// <summary>
+        /// When provided in a partial class, allows value of DateModified to be changed before setting.
+        /// </summary>
+        partial void SetDateModified(DateTime oldValue, ref DateTime newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of DateModified to be changed before returning.
+        /// </summary>
+        partial void GetDateModified(ref DateTime result);
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public DateTime DateModified
+        {
+            get
+            {
+                DateTime value = _DateModified;
+                GetDateModified(ref value);
+                return (_DateModified = value);
+            }
+            internal set
+            {
+                DateTime oldValue = _DateModified;
+                SetDateModified(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _DateModified = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.PersonRole> PersonRoles { get; protected set; }
+        [ForeignKey("PersonRole_PersonRoles_Id")]
+        public virtual ICollection<PersonRole> PersonRoles { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Genre> Genres { get; protected set; }
+        [ForeignKey("PersonRole_PersonRoles_Id")]
+        public virtual ICollection<Genre> Genres { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Artwork> Artwork { get; protected set; }
+        [ForeignKey("PersonRole_PersonRoles_Id")]
+        public virtual ICollection<Artwork> Artwork { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Rating> Ratings { get; protected set; }
+        [ForeignKey("PersonRole_PersonRoles_Id")]
+        public virtual ICollection<Rating> Ratings { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.MetadataProviderId> Sources { get; protected set; }
+        [ForeignKey("PersonRole_PersonRoles_Id")]
+        public virtual ICollection<MetadataProviderId> Sources { get; protected set; }
 
-   }
+    }
 }
 

+ 132 - 143
Jellyfin.Data/Entities/MetadataProvider.cs

@@ -1,158 +1,147 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class MetadataProvider
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected MetadataProvider()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static MetadataProvider CreateMetadataProviderUnsafe()
-      {
-         return new MetadataProvider();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="name"></param>
-      public MetadataProvider(string name)
-      {
-         if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
-         this.Name = name;
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="name"></param>
-      public static MetadataProvider Create(string name)
-      {
-         return new MetadataProvider(name);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class MetadataProvider
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected MetadataProvider()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static MetadataProvider CreateMetadataProviderUnsafe()
+        {
+            return new MetadataProvider();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="name"></param>
+        public MetadataProvider(string name)
+        {
+            if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
+            this.Name = name;
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="name"></param>
+        public static MetadataProvider Create(string name)
+        {
+            return new MetadataProvider(name);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
             {
-               _Id = value;
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Name
-      /// </summary>
-      protected string _Name;
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before setting.
-      /// </summary>
-      partial void SetName(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before returning.
-      /// </summary>
-      partial void GetName(ref string result);
-
-      /// <summary>
-      /// Required, Max length = 1024
-      /// </summary>
-      [Required]
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Name
-      {
-         get
-         {
-            string value = _Name;
-            GetName(ref value);
-            return (_Name = value);
-         }
-         set
-         {
-            string oldValue = _Name;
-            SetName(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Name
+        /// </summary>
+        protected string _Name;
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before setting.
+        /// </summary>
+        partial void SetName(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before returning.
+        /// </summary>
+        partial void GetName(ref string result);
+
+        /// <summary>
+        /// Required, Max length = 1024
+        /// </summary>
+        [Required]
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Name
+        {
+            get
             {
-               _Name = value;
+                string value = _Name;
+                GetName(ref value);
+                return (_Name = value);
             }
-         }
-      }
+            set
+            {
+                string oldValue = _Name;
+                SetName(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Name = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 167 - 177
Jellyfin.Data/Entities/MetadataProviderId.cs

@@ -1,189 +1,179 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class MetadataProviderId
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected MetadataProviderId()
-      {
-         // NOTE: This class has one-to-one associations with MetadataProviderId.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static MetadataProviderId CreateMetadataProviderIdUnsafe()
-      {
-         return new MetadataProviderId();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="providerid"></param>
-      /// <param name="_metadata0"></param>
-      /// <param name="_person1"></param>
-      /// <param name="_personrole2"></param>
-      /// <param name="_ratingsource3"></param>
-      public MetadataProviderId(string providerid, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.Person _person1, global::Jellyfin.Data.Entities.PersonRole _personrole2, global::Jellyfin.Data.Entities.RatingSource _ratingsource3)
-      {
-         // NOTE: This class has one-to-one associations with MetadataProviderId.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         if (string.IsNullOrEmpty(providerid)) throw new ArgumentNullException(nameof(providerid));
-         this.ProviderId = providerid;
-
-         if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
-         _metadata0.Sources.Add(this);
-
-         if (_person1 == null) throw new ArgumentNullException(nameof(_person1));
-         _person1.Sources.Add(this);
-
-         if (_personrole2 == null) throw new ArgumentNullException(nameof(_personrole2));
-         _personrole2.Sources.Add(this);
-
-         if (_ratingsource3 == null) throw new ArgumentNullException(nameof(_ratingsource3));
-         _ratingsource3.Source = this;
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="providerid"></param>
-      /// <param name="_metadata0"></param>
-      /// <param name="_person1"></param>
-      /// <param name="_personrole2"></param>
-      /// <param name="_ratingsource3"></param>
-      public static MetadataProviderId Create(string providerid, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.Person _person1, global::Jellyfin.Data.Entities.PersonRole _personrole2, global::Jellyfin.Data.Entities.RatingSource _ratingsource3)
-      {
-         return new MetadataProviderId(providerid, _metadata0, _person1, _personrole2, _ratingsource3);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class MetadataProviderId
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected MetadataProviderId()
+        {
+            // NOTE: This class has one-to-one associations with MetadataProviderId.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static MetadataProviderId CreateMetadataProviderIdUnsafe()
+        {
+            return new MetadataProviderId();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="providerid"></param>
+        /// <param name="_metadata0"></param>
+        /// <param name="_person1"></param>
+        /// <param name="_personrole2"></param>
+        /// <param name="_ratingsource3"></param>
+        public MetadataProviderId(string providerid, Metadata _metadata0, Person _person1, PersonRole _personrole2, RatingSource _ratingsource3)
+        {
+            // NOTE: This class has one-to-one associations with MetadataProviderId.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            if (string.IsNullOrEmpty(providerid)) throw new ArgumentNullException(nameof(providerid));
+            this.ProviderId = providerid;
+
+            if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
+            _metadata0.Sources.Add(this);
+
+            if (_person1 == null) throw new ArgumentNullException(nameof(_person1));
+            _person1.Sources.Add(this);
+
+            if (_personrole2 == null) throw new ArgumentNullException(nameof(_personrole2));
+            _personrole2.Sources.Add(this);
+
+            if (_ratingsource3 == null) throw new ArgumentNullException(nameof(_ratingsource3));
+            _ratingsource3.Source = this;
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="providerid"></param>
+        /// <param name="_metadata0"></param>
+        /// <param name="_person1"></param>
+        /// <param name="_personrole2"></param>
+        /// <param name="_ratingsource3"></param>
+        public static MetadataProviderId Create(string providerid, Metadata _metadata0, Person _person1, PersonRole _personrole2, RatingSource _ratingsource3)
+        {
+            return new MetadataProviderId(providerid, _metadata0, _person1, _personrole2, _ratingsource3);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
+            {
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for ProviderId
+        /// </summary>
+        protected string _ProviderId;
+        /// <summary>
+        /// When provided in a partial class, allows value of ProviderId to be changed before setting.
+        /// </summary>
+        partial void SetProviderId(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of ProviderId to be changed before returning.
+        /// </summary>
+        partial void GetProviderId(ref string result);
+
+        /// <summary>
+        /// Required, Max length = 255
+        /// </summary>
+        [Required]
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string ProviderId
+        {
+            get
             {
-               _Id = value;
+                string value = _ProviderId;
+                GetProviderId(ref value);
+                return (_ProviderId = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for ProviderId
-      /// </summary>
-      protected string _ProviderId;
-      /// <summary>
-      /// When provided in a partial class, allows value of ProviderId to be changed before setting.
-      /// </summary>
-      partial void SetProviderId(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of ProviderId to be changed before returning.
-      /// </summary>
-      partial void GetProviderId(ref string result);
-
-      /// <summary>
-      /// Required, Max length = 255
-      /// </summary>
-      [Required]
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string ProviderId
-      {
-         get
-         {
-            string value = _ProviderId;
-            GetProviderId(ref value);
-            return (_ProviderId = value);
-         }
-         set
-         {
-            string oldValue = _ProviderId;
-            SetProviderId(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _ProviderId = value;
+                string oldValue = _ProviderId;
+                SetProviderId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _ProviderId = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      public virtual global::Jellyfin.Data.Entities.MetadataProvider MetadataProvider { get; set; }
-
-   }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [ForeignKey("MetadataProvider_Id")]
+        public virtual MetadataProvider MetadataProvider { get; set; }
+
+    }
 }
 

+ 49 - 64
Jellyfin.Data/Entities/Movie.cs

@@ -1,84 +1,69 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Movie: global::Jellyfin.Data.Entities.LibraryItem
-   {
-      partial void Init();
+    public partial class Movie : LibraryItem
+    {
+        partial void Init();
 
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Movie(): base()
-      {
-         Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
-         MovieMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MovieMetadata>();
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Movie()
+        {
+            Releases = new HashSet<Release>();
+            MovieMetadata = new HashSet<MovieMetadata>();
 
-         Init();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Movie CreateMovieUnsafe()
-      {
-         return new Movie();
-      }
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Movie CreateMovieUnsafe()
+        {
+            return new Movie();
+        }
 
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public Movie(Guid urlid, DateTime dateadded)
-      {
-         this.UrlId = urlid;
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public Movie(Guid urlid, DateTime dateadded)
+        {
+            this.UrlId = urlid;
 
-         this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
-         this.MovieMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MovieMetadata>();
+            this.Releases = new HashSet<Release>();
+            this.MovieMetadata = new HashSet<MovieMetadata>();
 
-         Init();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public static Movie Create(Guid urlid, DateTime dateadded)
-      {
-         return new Movie(urlid, dateadded);
-      }
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public static Movie Create(Guid urlid, DateTime dateadded)
+        {
+            return new Movie(urlid, dateadded);
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
+        [ForeignKey("Release_Releases_Id")]
+        public virtual ICollection<Release> Releases { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.MovieMetadata> MovieMetadata { get; protected set; }
+        [ForeignKey("MovieMetadata_MovieMetadata_Id")]
+        public virtual ICollection<MovieMetadata> MovieMetadata { get; protected set; }
 
-   }
+    }
 }
 

+ 204 - 220
Jellyfin.Data/Entities/MovieMetadata.cs

@@ -1,239 +1,223 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class MovieMetadata: global::Jellyfin.Data.Entities.Metadata
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected MovieMetadata(): base()
-      {
-         Studios = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static MovieMetadata CreateMovieMetadataUnsafe()
-      {
-         return new MovieMetadata();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_movie0"></param>
-      public MovieMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Movie _movie0)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
-
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
-
-         if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0));
-         _movie0.MovieMetadata.Add(this);
-
-         this.Studios = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_movie0"></param>
-      public static MovieMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Movie _movie0)
-      {
-         return new MovieMetadata(title, language, dateadded, datemodified, _movie0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Outline
-      /// </summary>
-      protected string _Outline;
-      /// <summary>
-      /// When provided in a partial class, allows value of Outline to be changed before setting.
-      /// </summary>
-      partial void SetOutline(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Outline to be changed before returning.
-      /// </summary>
-      partial void GetOutline(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Outline
-      {
-         get
-         {
-            string value = _Outline;
-            GetOutline(ref value);
-            return (_Outline = value);
-         }
-         set
-         {
-            string oldValue = _Outline;
-            SetOutline(oldValue, ref value);
-            if (oldValue != value)
+    public partial class MovieMetadata : Metadata
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected MovieMetadata()
+        {
+            Studios = new HashSet<Company>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static MovieMetadata CreateMovieMetadataUnsafe()
+        {
+            return new MovieMetadata();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_movie0"></param>
+        public MovieMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Movie _movie0)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
+
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
+
+            if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0));
+            _movie0.MovieMetadata.Add(this);
+
+            this.Studios = new HashSet<Company>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_movie0"></param>
+        public static MovieMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Movie _movie0)
+        {
+            return new MovieMetadata(title, language, dateadded, datemodified, _movie0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Outline
+        /// </summary>
+        protected string _Outline;
+        /// <summary>
+        /// When provided in a partial class, allows value of Outline to be changed before setting.
+        /// </summary>
+        partial void SetOutline(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Outline to be changed before returning.
+        /// </summary>
+        partial void GetOutline(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Outline
+        {
+            get
             {
-               _Outline = value;
+                string value = _Outline;
+                GetOutline(ref value);
+                return (_Outline = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Plot
-      /// </summary>
-      protected string _Plot;
-      /// <summary>
-      /// When provided in a partial class, allows value of Plot to be changed before setting.
-      /// </summary>
-      partial void SetPlot(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Plot to be changed before returning.
-      /// </summary>
-      partial void GetPlot(ref string result);
-
-      /// <summary>
-      /// Max length = 65535
-      /// </summary>
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string Plot
-      {
-         get
-         {
-            string value = _Plot;
-            GetPlot(ref value);
-            return (_Plot = value);
-         }
-         set
-         {
-            string oldValue = _Plot;
-            SetPlot(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Plot = value;
+                string oldValue = _Outline;
+                SetOutline(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Outline = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Tagline
-      /// </summary>
-      protected string _Tagline;
-      /// <summary>
-      /// When provided in a partial class, allows value of Tagline to be changed before setting.
-      /// </summary>
-      partial void SetTagline(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Tagline to be changed before returning.
-      /// </summary>
-      partial void GetTagline(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Tagline
-      {
-         get
-         {
-            string value = _Tagline;
-            GetTagline(ref value);
-            return (_Tagline = value);
-         }
-         set
-         {
-            string oldValue = _Tagline;
-            SetTagline(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Plot
+        /// </summary>
+        protected string _Plot;
+        /// <summary>
+        /// When provided in a partial class, allows value of Plot to be changed before setting.
+        /// </summary>
+        partial void SetPlot(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Plot to be changed before returning.
+        /// </summary>
+        partial void GetPlot(ref string result);
+
+        /// <summary>
+        /// Max length = 65535
+        /// </summary>
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string Plot
+        {
+            get
             {
-               _Tagline = value;
+                string value = _Plot;
+                GetPlot(ref value);
+                return (_Plot = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Country
-      /// </summary>
-      protected string _Country;
-      /// <summary>
-      /// When provided in a partial class, allows value of Country to be changed before setting.
-      /// </summary>
-      partial void SetCountry(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Country to be changed before returning.
-      /// </summary>
-      partial void GetCountry(ref string result);
-
-      /// <summary>
-      /// Max length = 2
-      /// </summary>
-      [MaxLength(2)]
-      [StringLength(2)]
-      public string Country
-      {
-         get
-         {
-            string value = _Country;
-            GetCountry(ref value);
-            return (_Country = value);
-         }
-         set
-         {
-            string oldValue = _Country;
-            SetCountry(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Country = value;
+                string oldValue = _Plot;
+                SetPlot(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Plot = value;
+                }
             }
-         }
-      }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        }
+
+        /// <summary>
+        /// Backing field for Tagline
+        /// </summary>
+        protected string _Tagline;
+        /// <summary>
+        /// When provided in a partial class, allows value of Tagline to be changed before setting.
+        /// </summary>
+        partial void SetTagline(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Tagline to be changed before returning.
+        /// </summary>
+        partial void GetTagline(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Tagline
+        {
+            get
+            {
+                string value = _Tagline;
+                GetTagline(ref value);
+                return (_Tagline = value);
+            }
+            set
+            {
+                string oldValue = _Tagline;
+                SetTagline(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Tagline = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Country
+        /// </summary>
+        protected string _Country;
+        /// <summary>
+        /// When provided in a partial class, allows value of Country to be changed before setting.
+        /// </summary>
+        partial void SetCountry(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Country to be changed before returning.
+        /// </summary>
+        partial void GetCountry(ref string result);
+
+        /// <summary>
+        /// Max length = 2
+        /// </summary>
+        [MaxLength(2)]
+        [StringLength(2)]
+        public string Country
+        {
+            get
+            {
+                string value = _Country;
+                GetCountry(ref value);
+                return (_Country = value);
+            }
+            set
+            {
+                string oldValue = _Country;
+                SetCountry(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Country = value;
+                }
+            }
+        }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Company> Studios { get; protected set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("Company_Studios_Id")]
+        public virtual ICollection<Company> Studios { get; protected set; }
 
-   }
+    }
 }
 

+ 49 - 65
Jellyfin.Data/Entities/MusicAlbum.cs

@@ -1,84 +1,68 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class MusicAlbum: global::Jellyfin.Data.Entities.LibraryItem
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected MusicAlbum(): base()
-      {
-         MusicAlbumMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MusicAlbumMetadata>();
-         Tracks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Track>();
+    public partial class MusicAlbum : LibraryItem
+    {
+        partial void Init();
 
-         Init();
-      }
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected MusicAlbum()
+        {
+            MusicAlbumMetadata = new HashSet<MusicAlbumMetadata>();
+            Tracks = new HashSet<Track>();
 
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static MusicAlbum CreateMusicAlbumUnsafe()
-      {
-         return new MusicAlbum();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public MusicAlbum(Guid urlid, DateTime dateadded)
-      {
-         this.UrlId = urlid;
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static MusicAlbum CreateMusicAlbumUnsafe()
+        {
+            return new MusicAlbum();
+        }
 
-         this.MusicAlbumMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MusicAlbumMetadata>();
-         this.Tracks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Track>();
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public MusicAlbum(Guid urlid, DateTime dateadded)
+        {
+            this.UrlId = urlid;
 
-         Init();
-      }
+            this.MusicAlbumMetadata = new HashSet<MusicAlbumMetadata>();
+            this.Tracks = new HashSet<Track>();
 
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public static MusicAlbum Create(Guid urlid, DateTime dateadded)
-      {
-         return new MusicAlbum(urlid, dateadded);
-      }
+            Init();
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public static MusicAlbum Create(Guid urlid, DateTime dateadded)
+        {
+            return new MusicAlbum(urlid, dateadded);
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.MusicAlbumMetadata> MusicAlbumMetadata { get; protected set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("MusicAlbumMetadata_MusicAlbumMetadata_Id")]
+        public virtual ICollection<MusicAlbumMetadata> MusicAlbumMetadata { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Track> Tracks { get; protected set; }
+        [ForeignKey("Track_Tracks_Id")]
+        public virtual ICollection<Track> Tracks { get; protected set; }
 
-   }
+    }
 }
 

+ 169 - 184
Jellyfin.Data/Entities/MusicAlbumMetadata.cs

@@ -1,202 +1,187 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class MusicAlbumMetadata: global::Jellyfin.Data.Entities.Metadata
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected MusicAlbumMetadata(): base()
-      {
-         Labels = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static MusicAlbumMetadata CreateMusicAlbumMetadataUnsafe()
-      {
-         return new MusicAlbumMetadata();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_musicalbum0"></param>
-      public MusicAlbumMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
-
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
-
-         if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0));
-         _musicalbum0.MusicAlbumMetadata.Add(this);
-
-         this.Labels = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_musicalbum0"></param>
-      public static MusicAlbumMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0)
-      {
-         return new MusicAlbumMetadata(title, language, dateadded, datemodified, _musicalbum0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Barcode
-      /// </summary>
-      protected string _Barcode;
-      /// <summary>
-      /// When provided in a partial class, allows value of Barcode to be changed before setting.
-      /// </summary>
-      partial void SetBarcode(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Barcode to be changed before returning.
-      /// </summary>
-      partial void GetBarcode(ref string result);
-
-      /// <summary>
-      /// Max length = 255
-      /// </summary>
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string Barcode
-      {
-         get
-         {
-            string value = _Barcode;
-            GetBarcode(ref value);
-            return (_Barcode = value);
-         }
-         set
-         {
-            string oldValue = _Barcode;
-            SetBarcode(oldValue, ref value);
-            if (oldValue != value)
+    public partial class MusicAlbumMetadata : Metadata
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected MusicAlbumMetadata()
+        {
+            Labels = new HashSet<Company>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static MusicAlbumMetadata CreateMusicAlbumMetadataUnsafe()
+        {
+            return new MusicAlbumMetadata();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_musicalbum0"></param>
+        public MusicAlbumMetadata(string title, string language, DateTime dateadded, DateTime datemodified, MusicAlbum _musicalbum0)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
+
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
+
+            if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0));
+            _musicalbum0.MusicAlbumMetadata.Add(this);
+
+            this.Labels = new HashSet<Company>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_musicalbum0"></param>
+        public static MusicAlbumMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, MusicAlbum _musicalbum0)
+        {
+            return new MusicAlbumMetadata(title, language, dateadded, datemodified, _musicalbum0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Barcode
+        /// </summary>
+        protected string _Barcode;
+        /// <summary>
+        /// When provided in a partial class, allows value of Barcode to be changed before setting.
+        /// </summary>
+        partial void SetBarcode(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Barcode to be changed before returning.
+        /// </summary>
+        partial void GetBarcode(ref string result);
+
+        /// <summary>
+        /// Max length = 255
+        /// </summary>
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string Barcode
+        {
+            get
+            {
+                string value = _Barcode;
+                GetBarcode(ref value);
+                return (_Barcode = value);
+            }
+            set
+            {
+                string oldValue = _Barcode;
+                SetBarcode(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Barcode = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for LabelNumber
+        /// </summary>
+        protected string _LabelNumber;
+        /// <summary>
+        /// When provided in a partial class, allows value of LabelNumber to be changed before setting.
+        /// </summary>
+        partial void SetLabelNumber(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of LabelNumber to be changed before returning.
+        /// </summary>
+        partial void GetLabelNumber(ref string result);
+
+        /// <summary>
+        /// Max length = 255
+        /// </summary>
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string LabelNumber
+        {
+            get
+            {
+                string value = _LabelNumber;
+                GetLabelNumber(ref value);
+                return (_LabelNumber = value);
+            }
+            set
             {
-               _Barcode = value;
+                string oldValue = _LabelNumber;
+                SetLabelNumber(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _LabelNumber = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for LabelNumber
-      /// </summary>
-      protected string _LabelNumber;
-      /// <summary>
-      /// When provided in a partial class, allows value of LabelNumber to be changed before setting.
-      /// </summary>
-      partial void SetLabelNumber(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of LabelNumber to be changed before returning.
-      /// </summary>
-      partial void GetLabelNumber(ref string result);
-
-      /// <summary>
-      /// Max length = 255
-      /// </summary>
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string LabelNumber
-      {
-         get
-         {
-            string value = _LabelNumber;
-            GetLabelNumber(ref value);
-            return (_LabelNumber = value);
-         }
-         set
-         {
-            string oldValue = _LabelNumber;
-            SetLabelNumber(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Country
+        /// </summary>
+        protected string _Country;
+        /// <summary>
+        /// When provided in a partial class, allows value of Country to be changed before setting.
+        /// </summary>
+        partial void SetCountry(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Country to be changed before returning.
+        /// </summary>
+        partial void GetCountry(ref string result);
+
+        /// <summary>
+        /// Max length = 2
+        /// </summary>
+        [MaxLength(2)]
+        [StringLength(2)]
+        public string Country
+        {
+            get
             {
-               _LabelNumber = value;
+                string value = _Country;
+                GetCountry(ref value);
+                return (_Country = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Country
-      /// </summary>
-      protected string _Country;
-      /// <summary>
-      /// When provided in a partial class, allows value of Country to be changed before setting.
-      /// </summary>
-      partial void SetCountry(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Country to be changed before returning.
-      /// </summary>
-      partial void GetCountry(ref string result);
-
-      /// <summary>
-      /// Max length = 2
-      /// </summary>
-      [MaxLength(2)]
-      [StringLength(2)]
-      public string Country
-      {
-         get
-         {
-            string value = _Country;
-            GetCountry(ref value);
-            return (_Country = value);
-         }
-         set
-         {
-            string oldValue = _Country;
-            SetCountry(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Country = value;
+                string oldValue = _Country;
+                SetCountry(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Country = value;
+                }
             }
-         }
-      }
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Company> Labels { get; protected set; }
+        [ForeignKey("Company_Labels_Id")]
+        public virtual ICollection<Company> Labels { get; protected set; }
 
-   }
+    }
 }
 

+ 132 - 140
Jellyfin.Data/Entities/Permission.cs

@@ -1,152 +1,144 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
 using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Permission
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Permission()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Permission CreatePermissionUnsafe()
-      {
-         return new Permission();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="kind"></param>
-      /// <param name="value"></param>
-      /// <param name="_user0"></param>
-      /// <param name="_group1"></param>
-      public Permission(global::Jellyfin.Data.Enums.PermissionKind kind, bool value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1)
-      {
-         this.Kind = kind;
-
-         this.Value = value;
-
-         if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
-         _user0.Permissions.Add(this);
-
-         if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
-         _group1.GroupPermissions.Add(this);
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="kind"></param>
-      /// <param name="value"></param>
-      /// <param name="_user0"></param>
-      /// <param name="_group1"></param>
-      public static Permission Create(global::Jellyfin.Data.Enums.PermissionKind kind, bool value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1)
-      {
-         return new Permission(kind, value, _user0, _group1);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id { get; protected set; }
-
-      /// <summary>
-      /// Backing field for Kind
-      /// </summary>
-      protected global::Jellyfin.Data.Enums.PermissionKind _Kind;
-      /// <summary>
-      /// When provided in a partial class, allows value of Kind to be changed before setting.
-      /// </summary>
-      partial void SetKind(global::Jellyfin.Data.Enums.PermissionKind oldValue, ref global::Jellyfin.Data.Enums.PermissionKind newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Kind to be changed before returning.
-      /// </summary>
-      partial void GetKind(ref global::Jellyfin.Data.Enums.PermissionKind result);
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public global::Jellyfin.Data.Enums.PermissionKind Kind
-      {
-         get
-         {
-            global::Jellyfin.Data.Enums.PermissionKind value = _Kind;
-            GetKind(ref value);
-            return (_Kind = value);
-         }
-         set
-         {
-            global::Jellyfin.Data.Enums.PermissionKind oldValue = _Kind;
-            SetKind(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Permission
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Permission()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Permission CreatePermissionUnsafe()
+        {
+            return new Permission();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="kind"></param>
+        /// <param name="value"></param>
+        /// <param name="_user0"></param>
+        /// <param name="_group1"></param>
+        public Permission(Enums.PermissionKind kind, bool value, User _user0, Group _group1)
+        {
+            this.Kind = kind;
+
+            this.Value = value;
+
+            if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
+            _user0.Permissions.Add(this);
+
+            if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
+            _group1.GroupPermissions.Add(this);
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="kind"></param>
+        /// <param name="value"></param>
+        /// <param name="_user0"></param>
+        /// <param name="_group1"></param>
+        public static Permission Create(Enums.PermissionKind kind, bool value, User _user0, Group _group1)
+        {
+            return new Permission(kind, value, _user0, _group1);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id { get; protected set; }
+
+        /// <summary>
+        /// Backing field for Kind
+        /// </summary>
+        protected Enums.PermissionKind _Kind;
+        /// <summary>
+        /// When provided in a partial class, allows value of Kind to be changed before setting.
+        /// </summary>
+        partial void SetKind(Enums.PermissionKind oldValue, ref Enums.PermissionKind newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Kind to be changed before returning.
+        /// </summary>
+        partial void GetKind(ref Enums.PermissionKind result);
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public Enums.PermissionKind Kind
+        {
+            get
             {
-               _Kind = value;
-               OnPropertyChanged();
+                Enums.PermissionKind value = _Kind;
+                GetKind(ref value);
+                return (_Kind = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public bool Value { get; set; }
-
-      /// <summary>
-      /// Concurrency token
-      /// </summary>
-      [Timestamp]
-      public Byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      public virtual event PropertyChangedEventHandler PropertyChanged;
-
-      protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
-      {
-         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
-      }
-
-   }
+            set
+            {
+                Enums.PermissionKind oldValue = _Kind;
+                SetKind(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Kind = value;
+                    OnPropertyChanged();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public bool Value { get; set; }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+
+        public virtual event PropertyChangedEventHandler PropertyChanged;
+
+        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+        }
+
+    }
 }
 

+ 0 - 40
Jellyfin.Data/Entities/PermissionKind.cs

@@ -1,40 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-using System;
-
-namespace Jellyfin.Data.Enums
-{
-   public enum PermissionKind : Int32
-   {
-      IsAdministrator,
-      IsHidden,
-      IsDisabled,
-      BlockUnrateditems,
-      EnbleSharedDeviceControl,
-      EnableRemoteAccess,
-      EnableLiveTvManagement,
-      EnableLiveTvAccess,
-      EnableMediaPlayback,
-      EnableAudioPlaybackTranscoding,
-      EnableVideoPlaybackTranscoding,
-      EnableContentDeletion,
-      EnableContentDownloading,
-      EnableSyncTranscoding,
-      EnableMediaConversion,
-      EnableAllDevices,
-      EnableAllChannels,
-      EnableAllFolders,
-      EnablePublicSharing,
-      AccessSchedules
-   }
-}

+ 256 - 266
Jellyfin.Data/Entities/Person.cs

@@ -1,312 +1,302 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Person
-   {
-      partial void Init();
+    public partial class Person
+    {
+        partial void Init();
 
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Person()
-      {
-         Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Person()
+        {
+            Sources = new HashSet<MetadataProviderId>();
 
-         Init();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Person CreatePersonUnsafe()
-      {
-         return new Person();
-      }
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Person CreatePersonUnsafe()
+        {
+            return new Person();
+        }
 
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid"></param>
-      /// <param name="name"></param>
-      public Person(Guid urlid, string name, DateTime dateadded, DateTime datemodified)
-      {
-         this.UrlId = urlid;
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid"></param>
+        /// <param name="name"></param>
+        public Person(Guid urlid, string name, DateTime dateadded, DateTime datemodified)
+        {
+            this.UrlId = urlid;
 
-         if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
-         this.Name = name;
+            if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
+            this.Name = name;
 
-         this.Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
+            this.Sources = new HashSet<MetadataProviderId>();
 
-         Init();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="urlid"></param>
-      /// <param name="name"></param>
-      public static Person Create(Guid urlid, string name, DateTime dateadded, DateTime datemodified)
-      {
-         return new Person(urlid, name, dateadded, datemodified);
-      }
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="urlid"></param>
+        /// <param name="name"></param>
+        public static Person Create(Guid urlid, string name, DateTime dateadded, DateTime datemodified)
+        {
+            return new Person(urlid, name, dateadded, datemodified);
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
 
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
             {
-               _Id = value;
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
             }
-         }
-      }
+        }
 
-      /// <summary>
-      /// Backing field for UrlId
-      /// </summary>
-      protected Guid _UrlId;
-      /// <summary>
-      /// When provided in a partial class, allows value of UrlId to be changed before setting.
-      /// </summary>
-      partial void SetUrlId(Guid oldValue, ref Guid newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of UrlId to be changed before returning.
-      /// </summary>
-      partial void GetUrlId(ref Guid result);
+        /// <summary>
+        /// Backing field for UrlId
+        /// </summary>
+        protected Guid _UrlId;
+        /// <summary>
+        /// When provided in a partial class, allows value of UrlId to be changed before setting.
+        /// </summary>
+        partial void SetUrlId(Guid oldValue, ref Guid newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of UrlId to be changed before returning.
+        /// </summary>
+        partial void GetUrlId(ref Guid result);
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public Guid UrlId
-      {
-         get
-         {
-            Guid value = _UrlId;
-            GetUrlId(ref value);
-            return (_UrlId = value);
-         }
-         set
-         {
-            Guid oldValue = _UrlId;
-            SetUrlId(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public Guid UrlId
+        {
+            get
             {
-               _UrlId = value;
+                Guid value = _UrlId;
+                GetUrlId(ref value);
+                return (_UrlId = value);
             }
-         }
-      }
+            set
+            {
+                Guid oldValue = _UrlId;
+                SetUrlId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _UrlId = value;
+                }
+            }
+        }
 
-      /// <summary>
-      /// Backing field for Name
-      /// </summary>
-      protected string _Name;
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before setting.
-      /// </summary>
-      partial void SetName(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before returning.
-      /// </summary>
-      partial void GetName(ref string result);
+        /// <summary>
+        /// Backing field for Name
+        /// </summary>
+        protected string _Name;
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before setting.
+        /// </summary>
+        partial void SetName(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before returning.
+        /// </summary>
+        partial void GetName(ref string result);
 
-      /// <summary>
-      /// Required, Max length = 1024
-      /// </summary>
-      [Required]
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Name
-      {
-         get
-         {
-            string value = _Name;
-            GetName(ref value);
-            return (_Name = value);
-         }
-         set
-         {
-            string oldValue = _Name;
-            SetName(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Required, Max length = 1024
+        /// </summary>
+        [Required]
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Name
+        {
+            get
+            {
+                string value = _Name;
+                GetName(ref value);
+                return (_Name = value);
+            }
+            set
             {
-               _Name = value;
+                string oldValue = _Name;
+                SetName(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Name = value;
+                }
             }
-         }
-      }
+        }
 
-      /// <summary>
-      /// Backing field for SourceId
-      /// </summary>
-      protected string _SourceId;
-      /// <summary>
-      /// When provided in a partial class, allows value of SourceId to be changed before setting.
-      /// </summary>
-      partial void SetSourceId(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of SourceId to be changed before returning.
-      /// </summary>
-      partial void GetSourceId(ref string result);
+        /// <summary>
+        /// Backing field for SourceId
+        /// </summary>
+        protected string _SourceId;
+        /// <summary>
+        /// When provided in a partial class, allows value of SourceId to be changed before setting.
+        /// </summary>
+        partial void SetSourceId(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of SourceId to be changed before returning.
+        /// </summary>
+        partial void GetSourceId(ref string result);
 
-      /// <summary>
-      /// Max length = 255
-      /// </summary>
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string SourceId
-      {
-         get
-         {
-            string value = _SourceId;
-            GetSourceId(ref value);
-            return (_SourceId = value);
-         }
-         set
-         {
-            string oldValue = _SourceId;
-            SetSourceId(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Max length = 255
+        /// </summary>
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string SourceId
+        {
+            get
             {
-               _SourceId = value;
+                string value = _SourceId;
+                GetSourceId(ref value);
+                return (_SourceId = value);
             }
-         }
-      }
+            set
+            {
+                string oldValue = _SourceId;
+                SetSourceId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _SourceId = value;
+                }
+            }
+        }
 
-      /// <summary>
-      /// Backing field for DateAdded
-      /// </summary>
-      protected DateTime _DateAdded;
-      /// <summary>
-      /// When provided in a partial class, allows value of DateAdded to be changed before setting.
-      /// </summary>
-      partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of DateAdded to be changed before returning.
-      /// </summary>
-      partial void GetDateAdded(ref DateTime result);
+        /// <summary>
+        /// Backing field for DateAdded
+        /// </summary>
+        protected DateTime _DateAdded;
+        /// <summary>
+        /// When provided in a partial class, allows value of DateAdded to be changed before setting.
+        /// </summary>
+        partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of DateAdded to be changed before returning.
+        /// </summary>
+        partial void GetDateAdded(ref DateTime result);
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public DateTime DateAdded
-      {
-         get
-         {
-            DateTime value = _DateAdded;
-            GetDateAdded(ref value);
-            return (_DateAdded = value);
-         }
-         internal set
-         {
-            DateTime oldValue = _DateAdded;
-            SetDateAdded(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public DateTime DateAdded
+        {
+            get
+            {
+                DateTime value = _DateAdded;
+                GetDateAdded(ref value);
+                return (_DateAdded = value);
+            }
+            internal set
             {
-               _DateAdded = value;
+                DateTime oldValue = _DateAdded;
+                SetDateAdded(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _DateAdded = value;
+                }
             }
-         }
-      }
+        }
 
-      /// <summary>
-      /// Backing field for DateModified
-      /// </summary>
-      protected DateTime _DateModified;
-      /// <summary>
-      /// When provided in a partial class, allows value of DateModified to be changed before setting.
-      /// </summary>
-      partial void SetDateModified(DateTime oldValue, ref DateTime newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of DateModified to be changed before returning.
-      /// </summary>
-      partial void GetDateModified(ref DateTime result);
+        /// <summary>
+        /// Backing field for DateModified
+        /// </summary>
+        protected DateTime _DateModified;
+        /// <summary>
+        /// When provided in a partial class, allows value of DateModified to be changed before setting.
+        /// </summary>
+        partial void SetDateModified(DateTime oldValue, ref DateTime newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of DateModified to be changed before returning.
+        /// </summary>
+        partial void GetDateModified(ref DateTime result);
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public DateTime DateModified
-      {
-         get
-         {
-            DateTime value = _DateModified;
-            GetDateModified(ref value);
-            return (_DateModified = value);
-         }
-         internal set
-         {
-            DateTime oldValue = _DateModified;
-            SetDateModified(oldValue, ref value);
-            if (oldValue != value)
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public DateTime DateModified
+        {
+            get
+            {
+                DateTime value = _DateModified;
+                GetDateModified(ref value);
+                return (_DateModified = value);
+            }
+            internal set
             {
-               _DateModified = value;
+                DateTime oldValue = _DateModified;
+                SetDateModified(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _DateModified = value;
+                }
             }
-         }
-      }
+        }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.MetadataProviderId> Sources { get; protected set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("MetadataProviderId_Sources_Id")]
+        public virtual ICollection<MetadataProviderId> Sources { get; protected set; }
 
-   }
+    }
 }
 

+ 188 - 194
Jellyfin.Data/Entities/PersonRole.cs

@@ -1,215 +1,209 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class PersonRole
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected PersonRole()
-      {
-         // NOTE: This class has one-to-one associations with PersonRole.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static PersonRole CreatePersonRoleUnsafe()
-      {
-         return new PersonRole();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="type"></param>
-      /// <param name="_metadata0"></param>
-      public PersonRole(global::Jellyfin.Data.Enums.PersonRoleType type, global::Jellyfin.Data.Entities.Metadata _metadata0)
-      {
-         // NOTE: This class has one-to-one associations with PersonRole.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         this.Type = type;
-
-         if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
-         _metadata0.PersonRoles.Add(this);
-
-         this.Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="type"></param>
-      /// <param name="_metadata0"></param>
-      public static PersonRole Create(global::Jellyfin.Data.Enums.PersonRoleType type, global::Jellyfin.Data.Entities.Metadata _metadata0)
-      {
-         return new PersonRole(type, _metadata0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class PersonRole
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected PersonRole()
+        {
+            // NOTE: This class has one-to-one associations with PersonRole.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            Sources = new HashSet<MetadataProviderId>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static PersonRole CreatePersonRoleUnsafe()
+        {
+            return new PersonRole();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="type"></param>
+        /// <param name="_metadata0"></param>
+        public PersonRole(Enums.PersonRoleType type, Metadata _metadata0)
+        {
+            // NOTE: This class has one-to-one associations with PersonRole.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            this.Type = type;
+
+            if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
+            _metadata0.PersonRoles.Add(this);
+
+            this.Sources = new HashSet<MetadataProviderId>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="type"></param>
+        /// <param name="_metadata0"></param>
+        public static PersonRole Create(Enums.PersonRoleType type, Metadata _metadata0)
+        {
+            return new PersonRole(type, _metadata0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
+            {
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Role
+        /// </summary>
+        protected string _Role;
+        /// <summary>
+        /// When provided in a partial class, allows value of Role to be changed before setting.
+        /// </summary>
+        partial void SetRole(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Role to be changed before returning.
+        /// </summary>
+        partial void GetRole(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Role
+        {
+            get
             {
-               _Id = value;
+                string value = _Role;
+                GetRole(ref value);
+                return (_Role = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Role
-      /// </summary>
-      protected string _Role;
-      /// <summary>
-      /// When provided in a partial class, allows value of Role to be changed before setting.
-      /// </summary>
-      partial void SetRole(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Role to be changed before returning.
-      /// </summary>
-      partial void GetRole(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Role
-      {
-         get
-         {
-            string value = _Role;
-            GetRole(ref value);
-            return (_Role = value);
-         }
-         set
-         {
-            string oldValue = _Role;
-            SetRole(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Role = value;
+                string oldValue = _Role;
+                SetRole(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Role = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Type
-      /// </summary>
-      protected global::Jellyfin.Data.Enums.PersonRoleType _Type;
-      /// <summary>
-      /// When provided in a partial class, allows value of Type to be changed before setting.
-      /// </summary>
-      partial void SetType(global::Jellyfin.Data.Enums.PersonRoleType oldValue, ref global::Jellyfin.Data.Enums.PersonRoleType newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Type to be changed before returning.
-      /// </summary>
-      partial void GetType(ref global::Jellyfin.Data.Enums.PersonRoleType result);
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public global::Jellyfin.Data.Enums.PersonRoleType Type
-      {
-         get
-         {
-            global::Jellyfin.Data.Enums.PersonRoleType value = _Type;
-            GetType(ref value);
-            return (_Type = value);
-         }
-         set
-         {
-            global::Jellyfin.Data.Enums.PersonRoleType oldValue = _Type;
-            SetType(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Type
+        /// </summary>
+        protected Enums.PersonRoleType _Type;
+        /// <summary>
+        /// When provided in a partial class, allows value of Type to be changed before setting.
+        /// </summary>
+        partial void SetType(Enums.PersonRoleType oldValue, ref Enums.PersonRoleType newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Type to be changed before returning.
+        /// </summary>
+        partial void GetType(ref Enums.PersonRoleType result);
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public Enums.PersonRoleType Type
+        {
+            get
             {
-               _Type = value;
+                Enums.PersonRoleType value = _Type;
+                GetType(ref value);
+                return (_Type = value);
             }
-         }
-      }
+            set
+            {
+                Enums.PersonRoleType oldValue = _Type;
+                SetType(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Type = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /// <summary>
+        /// Required
+        /// </summary>
+        [ForeignKey("Person_Id")]
 
-      /// <summary>
-      /// Required
-      /// </summary>
-      public virtual global::Jellyfin.Data.Entities.Person Person { get; set; }
+        public virtual Person Person { get; set; }
 
-      public virtual global::Jellyfin.Data.Entities.Artwork Artwork { get; set; }
+        [ForeignKey("Artwork_Artwork_Id")]
+        public virtual Artwork Artwork { get; set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.MetadataProviderId> Sources { get; protected set; }
+        [ForeignKey("MetadataProviderId_Sources_Id")]
+        public virtual ICollection<MetadataProviderId> Sources { get; protected set; }
 
-   }
+    }
 }
 

+ 49 - 65
Jellyfin.Data/Entities/Photo.cs

@@ -1,84 +1,68 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Photo: global::Jellyfin.Data.Entities.LibraryItem
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Photo(): base()
-      {
-         PhotoMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PhotoMetadata>();
-         Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
+    public partial class Photo : LibraryItem
+    {
+        partial void Init();
 
-         Init();
-      }
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Photo()
+        {
+            PhotoMetadata = new HashSet<PhotoMetadata>();
+            Releases = new HashSet<Release>();
 
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Photo CreatePhotoUnsafe()
-      {
-         return new Photo();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public Photo(Guid urlid, DateTime dateadded)
-      {
-         this.UrlId = urlid;
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Photo CreatePhotoUnsafe()
+        {
+            return new Photo();
+        }
 
-         this.PhotoMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PhotoMetadata>();
-         this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public Photo(Guid urlid, DateTime dateadded)
+        {
+            this.UrlId = urlid;
 
-         Init();
-      }
+            this.PhotoMetadata = new HashSet<PhotoMetadata>();
+            this.Releases = new HashSet<Release>();
 
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public static Photo Create(Guid urlid, DateTime dateadded)
-      {
-         return new Photo(urlid, dateadded);
-      }
+            Init();
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public static Photo Create(Guid urlid, DateTime dateadded)
+        {
+            return new Photo(urlid, dateadded);
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.PhotoMetadata> PhotoMetadata { get; protected set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("PhotoMetadata_PhotoMetadata_Id")]
+        public virtual ICollection<PhotoMetadata> PhotoMetadata { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
+        [ForeignKey("Release_Releases_Id")]
+        public virtual ICollection<Release> Releases { get; protected set; }
 
-   }
+    }
 }
 

+ 50 - 68
Jellyfin.Data/Entities/PhotoMetadata.cs

@@ -1,86 +1,68 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class PhotoMetadata: global::Jellyfin.Data.Entities.Metadata
-   {
-      partial void Init();
+    public partial class PhotoMetadata : Metadata
+    {
+        partial void Init();
 
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected PhotoMetadata(): base()
-      {
-         Init();
-      }
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected PhotoMetadata()
+        {
+            Init();
+        }
 
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static PhotoMetadata CreatePhotoMetadataUnsafe()
-      {
-         return new PhotoMetadata();
-      }
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static PhotoMetadata CreatePhotoMetadataUnsafe()
+        {
+            return new PhotoMetadata();
+        }
 
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_photo0"></param>
-      public PhotoMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Photo _photo0)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_photo0"></param>
+        public PhotoMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Photo _photo0)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
 
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
 
-         if (_photo0 == null) throw new ArgumentNullException(nameof(_photo0));
-         _photo0.PhotoMetadata.Add(this);
+            if (_photo0 == null) throw new ArgumentNullException(nameof(_photo0));
+            _photo0.PhotoMetadata.Add(this);
 
 
-         Init();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_photo0"></param>
-      public static PhotoMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Photo _photo0)
-      {
-         return new PhotoMetadata(title, language, dateadded, datemodified, _photo0);
-      }
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_photo0"></param>
+        public static PhotoMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Photo _photo0)
+        {
+            return new PhotoMetadata(title, language, dateadded, datemodified, _photo0);
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 99 - 109
Jellyfin.Data/Entities/Preference.cs

@@ -1,117 +1,107 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Preference
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Preference()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Preference CreatePreferenceUnsafe()
-      {
-         return new Preference();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="kind"></param>
-      /// <param name="value"></param>
-      /// <param name="_user0"></param>
-      /// <param name="_group1"></param>
-      public Preference(global::Jellyfin.Data.Enums.PreferenceKind kind, string value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1)
-      {
-         this.Kind = kind;
-
-         if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(value));
-         this.Value = value;
-
-         if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
-         _user0.Preferences.Add(this);
-
-         if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
-         _group1.Preferences.Add(this);
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="kind"></param>
-      /// <param name="value"></param>
-      /// <param name="_user0"></param>
-      /// <param name="_group1"></param>
-      public static Preference Create(global::Jellyfin.Data.Enums.PreferenceKind kind, string value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1)
-      {
-         return new Preference(kind, value, _user0, _group1);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id { get; protected set; }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public global::Jellyfin.Data.Enums.PreferenceKind Kind { get; set; }
-
-      /// <summary>
-      /// Required, Max length = 65535
-      /// </summary>
-      [Required]
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string Value { get; set; }
-
-      /// <summary>
-      /// Concurrency token
-      /// </summary>
-      [Timestamp]
-      public Byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-   }
+    public partial class Preference
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Preference()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Preference CreatePreferenceUnsafe()
+        {
+            return new Preference();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="kind"></param>
+        /// <param name="value"></param>
+        /// <param name="_user0"></param>
+        /// <param name="_group1"></param>
+        public Preference(Enums.PreferenceKind kind, string value, User _user0, Group _group1)
+        {
+            this.Kind = kind;
+
+            if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(value));
+            this.Value = value;
+
+            if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
+            _user0.Preferences.Add(this);
+
+            if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
+            _group1.Preferences.Add(this);
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="kind"></param>
+        /// <param name="value"></param>
+        /// <param name="_user0"></param>
+        /// <param name="_group1"></param>
+        public static Preference Create(Enums.PreferenceKind kind, string value, User _user0, Group _group1)
+        {
+            return new Preference(kind, value, _user0, _group1);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id { get; protected set; }
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public Enums.PreferenceKind Kind { get; set; }
+
+        /// <summary>
+        /// Required, Max length = 65535
+        /// </summary>
+        [Required]
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string Value { get; set; }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+
+    }
 }
 

+ 0 - 27
Jellyfin.Data/Entities/PreferenceKind.cs

@@ -1,27 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-using System;
-
-namespace Jellyfin.Data.Enums
-{
-   public enum PreferenceKind : Int32
-   {
-      MaxParentalRating,
-      BlockedTags,
-      RemoteClientBitrateLimit,
-      EnabledDevices,
-      EnabledChannels,
-      EnabledFolders,
-      EnableContentDeletionFromFolders
-   }
-}

+ 115 - 125
Jellyfin.Data/Entities/ProviderMapping.cs

@@ -1,133 +1,123 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class ProviderMapping
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected ProviderMapping()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static ProviderMapping CreateProviderMappingUnsafe()
-      {
-         return new ProviderMapping();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="providername"></param>
-      /// <param name="providersecrets"></param>
-      /// <param name="providerdata"></param>
-      /// <param name="_user0"></param>
-      /// <param name="_group1"></param>
-      public ProviderMapping(string providername, string providersecrets, string providerdata, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1)
-      {
-         if (string.IsNullOrEmpty(providername)) throw new ArgumentNullException(nameof(providername));
-         this.ProviderName = providername;
-
-         if (string.IsNullOrEmpty(providersecrets)) throw new ArgumentNullException(nameof(providersecrets));
-         this.ProviderSecrets = providersecrets;
-
-         if (string.IsNullOrEmpty(providerdata)) throw new ArgumentNullException(nameof(providerdata));
-         this.ProviderData = providerdata;
-
-         if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
-         _user0.ProviderMappings.Add(this);
-
-         if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
-         _group1.ProviderMappings.Add(this);
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="providername"></param>
-      /// <param name="providersecrets"></param>
-      /// <param name="providerdata"></param>
-      /// <param name="_user0"></param>
-      /// <param name="_group1"></param>
-      public static ProviderMapping Create(string providername, string providersecrets, string providerdata, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1)
-      {
-         return new ProviderMapping(providername, providersecrets, providerdata, _user0, _group1);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id { get; protected set; }
-
-      /// <summary>
-      /// Required, Max length = 255
-      /// </summary>
-      [Required]
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string ProviderName { get; set; }
-
-      /// <summary>
-      /// Required, Max length = 65535
-      /// </summary>
-      [Required]
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string ProviderSecrets { get; set; }
-
-      /// <summary>
-      /// Required, Max length = 65535
-      /// </summary>
-      [Required]
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string ProviderData { get; set; }
-
-      /// <summary>
-      /// Concurrency token
-      /// </summary>
-      [Timestamp]
-      public Byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-   }
+    public partial class ProviderMapping
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected ProviderMapping()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static ProviderMapping CreateProviderMappingUnsafe()
+        {
+            return new ProviderMapping();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="providername"></param>
+        /// <param name="providersecrets"></param>
+        /// <param name="providerdata"></param>
+        /// <param name="_user0"></param>
+        /// <param name="_group1"></param>
+        public ProviderMapping(string providername, string providersecrets, string providerdata, User _user0, Group _group1)
+        {
+            if (string.IsNullOrEmpty(providername)) throw new ArgumentNullException(nameof(providername));
+            this.ProviderName = providername;
+
+            if (string.IsNullOrEmpty(providersecrets)) throw new ArgumentNullException(nameof(providersecrets));
+            this.ProviderSecrets = providersecrets;
+
+            if (string.IsNullOrEmpty(providerdata)) throw new ArgumentNullException(nameof(providerdata));
+            this.ProviderData = providerdata;
+
+            if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
+            _user0.ProviderMappings.Add(this);
+
+            if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
+            _group1.ProviderMappings.Add(this);
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="providername"></param>
+        /// <param name="providersecrets"></param>
+        /// <param name="providerdata"></param>
+        /// <param name="_user0"></param>
+        /// <param name="_group1"></param>
+        public static ProviderMapping Create(string providername, string providersecrets, string providerdata, User _user0, Group _group1)
+        {
+            return new ProviderMapping(providername, providersecrets, providerdata, _user0, _group1);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id { get; protected set; }
+
+        /// <summary>
+        /// Required, Max length = 255
+        /// </summary>
+        [Required]
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string ProviderName { get; set; }
+
+        /// <summary>
+        /// Required, Max length = 65535
+        /// </summary>
+        [Required]
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string ProviderSecrets { get; set; }
+
+        /// <summary>
+        /// Required, Max length = 65535
+        /// </summary>
+        [Required]
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string ProviderData { get; set; }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+
+    }
 }
 

+ 173 - 183
Jellyfin.Data/Entities/Rating.cs

@@ -1,197 +1,187 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Rating
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Rating()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Rating CreateRatingUnsafe()
-      {
-         return new Rating();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="value"></param>
-      /// <param name="_metadata0"></param>
-      public Rating(double value, global::Jellyfin.Data.Entities.Metadata _metadata0)
-      {
-         this.Value = value;
-
-         if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
-         _metadata0.Ratings.Add(this);
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="value"></param>
-      /// <param name="_metadata0"></param>
-      public static Rating Create(double value, global::Jellyfin.Data.Entities.Metadata _metadata0)
-      {
-         return new Rating(value, _metadata0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Rating
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Rating()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Rating CreateRatingUnsafe()
+        {
+            return new Rating();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="_metadata0"></param>
+        public Rating(double value, Metadata _metadata0)
+        {
+            this.Value = value;
+
+            if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
+            _metadata0.Ratings.Add(this);
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="value"></param>
+        /// <param name="_metadata0"></param>
+        public static Rating Create(double value, Metadata _metadata0)
+        {
+            return new Rating(value, _metadata0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
+            {
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
+            }
+            protected set
+            {
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Value
+        /// </summary>
+        protected double _Value;
+        /// <summary>
+        /// When provided in a partial class, allows value of Value to be changed before setting.
+        /// </summary>
+        partial void SetValue(double oldValue, ref double newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Value to be changed before returning.
+        /// </summary>
+        partial void GetValue(ref double result);
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public double Value
+        {
+            get
+            {
+                double value = _Value;
+                GetValue(ref value);
+                return (_Value = value);
+            }
+            set
             {
-               _Id = value;
+                double oldValue = _Value;
+                SetValue(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Value = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Value
-      /// </summary>
-      protected double _Value;
-      /// <summary>
-      /// When provided in a partial class, allows value of Value to be changed before setting.
-      /// </summary>
-      partial void SetValue(double oldValue, ref double newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Value to be changed before returning.
-      /// </summary>
-      partial void GetValue(ref double result);
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public double Value
-      {
-         get
-         {
-            double value = _Value;
-            GetValue(ref value);
-            return (_Value = value);
-         }
-         set
-         {
-            double oldValue = _Value;
-            SetValue(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Votes
+        /// </summary>
+        protected int? _Votes;
+        /// <summary>
+        /// When provided in a partial class, allows value of Votes to be changed before setting.
+        /// </summary>
+        partial void SetVotes(int? oldValue, ref int? newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Votes to be changed before returning.
+        /// </summary>
+        partial void GetVotes(ref int? result);
+
+        public int? Votes
+        {
+            get
             {
-               _Value = value;
+                int? value = _Votes;
+                GetVotes(ref value);
+                return (_Votes = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Votes
-      /// </summary>
-      protected int? _Votes;
-      /// <summary>
-      /// When provided in a partial class, allows value of Votes to be changed before setting.
-      /// </summary>
-      partial void SetVotes(int? oldValue, ref int? newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Votes to be changed before returning.
-      /// </summary>
-      partial void GetVotes(ref int? result);
-
-      public int? Votes
-      {
-         get
-         {
-            int? value = _Votes;
-            GetVotes(ref value);
-            return (_Votes = value);
-         }
-         set
-         {
-            int? oldValue = _Votes;
-            SetVotes(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Votes = value;
+                int? oldValue = _Votes;
+                SetVotes(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Votes = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      /// <summary>
-      /// If this is NULL it&apos;s the internal user rating.
-      /// </summary>
-      public virtual global::Jellyfin.Data.Entities.RatingSource RatingType { get; set; }
-
-   }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+
+        /// <summary>
+        /// If this is NULL it&apos;s the internal user rating.
+        /// </summary>
+        [ForeignKey("RatingSource_RatingType_Id")]
+        public virtual RatingSource RatingType { get; set; }
+
+    }
 }
 

+ 215 - 226
Jellyfin.Data/Entities/RatingSource.cs

@@ -1,242 +1,231 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   /// <summary>
-   /// This is the entity to store review ratings, not age ratings
-   /// </summary>
-   public partial class RatingSource
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected RatingSource()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static RatingSource CreateRatingSourceUnsafe()
-      {
-         return new RatingSource();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="maximumvalue"></param>
-      /// <param name="minimumvalue"></param>
-      /// <param name="_rating0"></param>
-      public RatingSource(double maximumvalue, double minimumvalue, global::Jellyfin.Data.Entities.Rating _rating0)
-      {
-         this.MaximumValue = maximumvalue;
-
-         this.MinimumValue = minimumvalue;
-
-         if (_rating0 == null) throw new ArgumentNullException(nameof(_rating0));
-         _rating0.RatingType = this;
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="maximumvalue"></param>
-      /// <param name="minimumvalue"></param>
-      /// <param name="_rating0"></param>
-      public static RatingSource Create(double maximumvalue, double minimumvalue, global::Jellyfin.Data.Entities.Rating _rating0)
-      {
-         return new RatingSource(maximumvalue, minimumvalue, _rating0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    /// <summary>
+    /// This is the entity to store review ratings, not age ratings
+    /// </summary>
+    public partial class RatingSource
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected RatingSource()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static RatingSource CreateRatingSourceUnsafe()
+        {
+            return new RatingSource();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="maximumvalue"></param>
+        /// <param name="minimumvalue"></param>
+        /// <param name="_rating0"></param>
+        public RatingSource(double maximumvalue, double minimumvalue, Rating _rating0)
+        {
+            this.MaximumValue = maximumvalue;
+
+            this.MinimumValue = minimumvalue;
+
+            if (_rating0 == null) throw new ArgumentNullException(nameof(_rating0));
+            _rating0.RatingType = this;
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="maximumvalue"></param>
+        /// <param name="minimumvalue"></param>
+        /// <param name="_rating0"></param>
+        public static RatingSource Create(double maximumvalue, double minimumvalue, Rating _rating0)
+        {
+            return new RatingSource(maximumvalue, minimumvalue, _rating0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
             {
-               _Id = value;
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Name
-      /// </summary>
-      protected string _Name;
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before setting.
-      /// </summary>
-      partial void SetName(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before returning.
-      /// </summary>
-      partial void GetName(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Name
-      {
-         get
-         {
-            string value = _Name;
-            GetName(ref value);
-            return (_Name = value);
-         }
-         set
-         {
-            string oldValue = _Name;
-            SetName(oldValue, ref value);
-            if (oldValue != value)
+            protected set
             {
-               _Name = value;
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for MaximumValue
-      /// </summary>
-      protected double _MaximumValue;
-      /// <summary>
-      /// When provided in a partial class, allows value of MaximumValue to be changed before setting.
-      /// </summary>
-      partial void SetMaximumValue(double oldValue, ref double newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of MaximumValue to be changed before returning.
-      /// </summary>
-      partial void GetMaximumValue(ref double result);
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public double MaximumValue
-      {
-         get
-         {
-            double value = _MaximumValue;
-            GetMaximumValue(ref value);
-            return (_MaximumValue = value);
-         }
-         set
-         {
-            double oldValue = _MaximumValue;
-            SetMaximumValue(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Name
+        /// </summary>
+        protected string _Name;
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before setting.
+        /// </summary>
+        partial void SetName(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before returning.
+        /// </summary>
+        partial void GetName(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Name
+        {
+            get
             {
-               _MaximumValue = value;
+                string value = _Name;
+                GetName(ref value);
+                return (_Name = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for MinimumValue
-      /// </summary>
-      protected double _MinimumValue;
-      /// <summary>
-      /// When provided in a partial class, allows value of MinimumValue to be changed before setting.
-      /// </summary>
-      partial void SetMinimumValue(double oldValue, ref double newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of MinimumValue to be changed before returning.
-      /// </summary>
-      partial void GetMinimumValue(ref double result);
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public double MinimumValue
-      {
-         get
-         {
-            double value = _MinimumValue;
-            GetMinimumValue(ref value);
-            return (_MinimumValue = value);
-         }
-         set
-         {
-            double oldValue = _MinimumValue;
-            SetMinimumValue(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _MinimumValue = value;
+                string oldValue = _Name;
+                SetName(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Name = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      public virtual global::Jellyfin.Data.Entities.MetadataProviderId Source { get; set; }
-
-   }
+        }
+
+        /// <summary>
+        /// Backing field for MaximumValue
+        /// </summary>
+        protected double _MaximumValue;
+        /// <summary>
+        /// When provided in a partial class, allows value of MaximumValue to be changed before setting.
+        /// </summary>
+        partial void SetMaximumValue(double oldValue, ref double newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of MaximumValue to be changed before returning.
+        /// </summary>
+        partial void GetMaximumValue(ref double result);
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public double MaximumValue
+        {
+            get
+            {
+                double value = _MaximumValue;
+                GetMaximumValue(ref value);
+                return (_MaximumValue = value);
+            }
+            set
+            {
+                double oldValue = _MaximumValue;
+                SetMaximumValue(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _MaximumValue = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for MinimumValue
+        /// </summary>
+        protected double _MinimumValue;
+        /// <summary>
+        /// When provided in a partial class, allows value of MinimumValue to be changed before setting.
+        /// </summary>
+        partial void SetMinimumValue(double oldValue, ref double newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of MinimumValue to be changed before returning.
+        /// </summary>
+        partial void GetMinimumValue(ref double result);
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public double MinimumValue
+        {
+            get
+            {
+                double value = _MinimumValue;
+                GetMinimumValue(ref value);
+                return (_MinimumValue = value);
+            }
+            set
+            {
+                double oldValue = _MinimumValue;
+                SetMinimumValue(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _MinimumValue = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("MetadataProviderId_Source_Id")]
+        public virtual MetadataProviderId Source { get; set; }
+
+    }
 }
 

+ 175 - 184
Jellyfin.Data/Entities/Release.cs

@@ -1,197 +1,188 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Release
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Release()
-      {
-         MediaFiles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFile>();
-         Chapters = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Chapter>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Release CreateReleaseUnsafe()
-      {
-         return new Release();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="name"></param>
-      /// <param name="_movie0"></param>
-      /// <param name="_episode1"></param>
-      /// <param name="_track2"></param>
-      /// <param name="_customitem3"></param>
-      /// <param name="_book4"></param>
-      /// <param name="_photo5"></param>
-      public Release(string name, global::Jellyfin.Data.Entities.Movie _movie0, global::Jellyfin.Data.Entities.Episode _episode1, global::Jellyfin.Data.Entities.Track _track2, global::Jellyfin.Data.Entities.CustomItem _customitem3, global::Jellyfin.Data.Entities.Book _book4, global::Jellyfin.Data.Entities.Photo _photo5)
-      {
-         if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
-         this.Name = name;
-
-         if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0));
-         _movie0.Releases.Add(this);
-
-         if (_episode1 == null) throw new ArgumentNullException(nameof(_episode1));
-         _episode1.Releases.Add(this);
-
-         if (_track2 == null) throw new ArgumentNullException(nameof(_track2));
-         _track2.Releases.Add(this);
-
-         if (_customitem3 == null) throw new ArgumentNullException(nameof(_customitem3));
-         _customitem3.Releases.Add(this);
-
-         if (_book4 == null) throw new ArgumentNullException(nameof(_book4));
-         _book4.Releases.Add(this);
-
-         if (_photo5 == null) throw new ArgumentNullException(nameof(_photo5));
-         _photo5.Releases.Add(this);
-
-         this.MediaFiles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFile>();
-         this.Chapters = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Chapter>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="name"></param>
-      /// <param name="_movie0"></param>
-      /// <param name="_episode1"></param>
-      /// <param name="_track2"></param>
-      /// <param name="_customitem3"></param>
-      /// <param name="_book4"></param>
-      /// <param name="_photo5"></param>
-      public static Release Create(string name, global::Jellyfin.Data.Entities.Movie _movie0, global::Jellyfin.Data.Entities.Episode _episode1, global::Jellyfin.Data.Entities.Track _track2, global::Jellyfin.Data.Entities.CustomItem _customitem3, global::Jellyfin.Data.Entities.Book _book4, global::Jellyfin.Data.Entities.Photo _photo5)
-      {
-         return new Release(name, _movie0, _episode1, _track2, _customitem3, _book4, _photo5);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Id
-      /// </summary>
-      internal int _Id;
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before setting.
-      /// </summary>
-      partial void SetId(int oldValue, ref int newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Id to be changed before returning.
-      /// </summary>
-      partial void GetId(ref int result);
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public int Id
-      {
-         get
-         {
-            int value = _Id;
-            GetId(ref value);
-            return (_Id = value);
-         }
-         protected set
-         {
-            int oldValue = _Id;
-            SetId(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Release
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Release()
+        {
+            MediaFiles = new HashSet<MediaFile>();
+            Chapters = new HashSet<Chapter>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Release CreateReleaseUnsafe()
+        {
+            return new Release();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="_movie0"></param>
+        /// <param name="_episode1"></param>
+        /// <param name="_track2"></param>
+        /// <param name="_customitem3"></param>
+        /// <param name="_book4"></param>
+        /// <param name="_photo5"></param>
+        public Release(string name, Movie _movie0, Episode _episode1, Track _track2, CustomItem _customitem3, Book _book4, Photo _photo5)
+        {
+            if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
+            this.Name = name;
+
+            if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0));
+            _movie0.Releases.Add(this);
+
+            if (_episode1 == null) throw new ArgumentNullException(nameof(_episode1));
+            _episode1.Releases.Add(this);
+
+            if (_track2 == null) throw new ArgumentNullException(nameof(_track2));
+            _track2.Releases.Add(this);
+
+            if (_customitem3 == null) throw new ArgumentNullException(nameof(_customitem3));
+            _customitem3.Releases.Add(this);
+
+            if (_book4 == null) throw new ArgumentNullException(nameof(_book4));
+            _book4.Releases.Add(this);
+
+            if (_photo5 == null) throw new ArgumentNullException(nameof(_photo5));
+            _photo5.Releases.Add(this);
+
+            this.MediaFiles = new HashSet<MediaFile>();
+            this.Chapters = new HashSet<Chapter>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="_movie0"></param>
+        /// <param name="_episode1"></param>
+        /// <param name="_track2"></param>
+        /// <param name="_customitem3"></param>
+        /// <param name="_book4"></param>
+        /// <param name="_photo5"></param>
+        public static Release Create(string name, Movie _movie0, Episode _episode1, Track _track2, CustomItem _customitem3, Book _book4, Photo _photo5)
+        {
+            return new Release(name, _movie0, _episode1, _track2, _customitem3, _book4, _photo5);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Id
+        /// </summary>
+        internal int _Id;
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before setting.
+        /// </summary>
+        partial void SetId(int oldValue, ref int newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Id to be changed before returning.
+        /// </summary>
+        partial void GetId(ref int result);
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id
+        {
+            get
             {
-               _Id = value;
+                int value = _Id;
+                GetId(ref value);
+                return (_Id = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Name
-      /// </summary>
-      protected string _Name;
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before setting.
-      /// </summary>
-      partial void SetName(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Name to be changed before returning.
-      /// </summary>
-      partial void GetName(ref string result);
-
-      /// <summary>
-      /// Required, Max length = 1024
-      /// </summary>
-      [Required]
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Name
-      {
-         get
-         {
-            string value = _Name;
-            GetName(ref value);
-            return (_Name = value);
-         }
-         set
-         {
-            string oldValue = _Name;
-            SetName(oldValue, ref value);
-            if (oldValue != value)
+            protected set
             {
-               _Name = value;
+                int oldValue = _Id;
+                SetId(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Id = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] Timestamp { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.MediaFile> MediaFiles { get; protected set; }
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.Chapter> Chapters { get; protected set; }
-
-   }
+        }
+
+        /// <summary>
+        /// Backing field for Name
+        /// </summary>
+        protected string _Name;
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before setting.
+        /// </summary>
+        partial void SetName(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Name to be changed before returning.
+        /// </summary>
+        partial void GetName(ref string result);
+
+        /// <summary>
+        /// Required, Max length = 1024
+        /// </summary>
+        [Required]
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Name
+        {
+            get
+            {
+                string value = _Name;
+                GetName(ref value);
+                return (_Name = value);
+            }
+            set
+            {
+                string oldValue = _Name;
+                SetName(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Name = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("MediaFile_MediaFiles_Id")]
+        public virtual ICollection<MediaFile> MediaFiles { get; protected set; }
+
+        [ForeignKey("Chapter_Chapters_Id")]
+        public virtual ICollection<Chapter> Chapters { get; protected set; }
+
+    }
 }
 

+ 98 - 114
Jellyfin.Data/Entities/Season.cs

@@ -1,127 +1,111 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Season: global::Jellyfin.Data.Entities.LibraryItem
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Season(): base()
-      {
-         // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         SeasonMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.SeasonMetadata>();
-         Episodes = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Episode>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Season CreateSeasonUnsafe()
-      {
-         return new Season();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      /// <param name="_series0"></param>
-      public Season(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Series _series0)
-      {
-         // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         this.UrlId = urlid;
-
-         if (_series0 == null) throw new ArgumentNullException(nameof(_series0));
-         _series0.Seasons.Add(this);
-
-         this.SeasonMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.SeasonMetadata>();
-         this.Episodes = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Episode>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      /// <param name="_series0"></param>
-      public static Season Create(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Series _series0)
-      {
-         return new Season(urlid, dateadded, _series0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for SeasonNumber
-      /// </summary>
-      protected int? _SeasonNumber;
-      /// <summary>
-      /// When provided in a partial class, allows value of SeasonNumber to be changed before setting.
-      /// </summary>
-      partial void SetSeasonNumber(int? oldValue, ref int? newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of SeasonNumber to be changed before returning.
-      /// </summary>
-      partial void GetSeasonNumber(ref int? result);
-
-      public int? SeasonNumber
-      {
-         get
-         {
-            int? value = _SeasonNumber;
-            GetSeasonNumber(ref value);
-            return (_SeasonNumber = value);
-         }
-         set
-         {
-            int? oldValue = _SeasonNumber;
-            SetSeasonNumber(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Season : LibraryItem
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Season()
+        {
+            // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            SeasonMetadata = new HashSet<SeasonMetadata>();
+            Episodes = new HashSet<Episode>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Season CreateSeasonUnsafe()
+        {
+            return new Season();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        /// <param name="_series0"></param>
+        public Season(Guid urlid, DateTime dateadded, Series _series0)
+        {
+            // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            this.UrlId = urlid;
+
+            if (_series0 == null) throw new ArgumentNullException(nameof(_series0));
+            _series0.Seasons.Add(this);
+
+            this.SeasonMetadata = new HashSet<SeasonMetadata>();
+            this.Episodes = new HashSet<Episode>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        /// <param name="_series0"></param>
+        public static Season Create(Guid urlid, DateTime dateadded, Series _series0)
+        {
+            return new Season(urlid, dateadded, _series0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for SeasonNumber
+        /// </summary>
+        protected int? _SeasonNumber;
+        /// <summary>
+        /// When provided in a partial class, allows value of SeasonNumber to be changed before setting.
+        /// </summary>
+        partial void SetSeasonNumber(int? oldValue, ref int? newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of SeasonNumber to be changed before returning.
+        /// </summary>
+        partial void GetSeasonNumber(ref int? result);
+
+        public int? SeasonNumber
+        {
+            get
             {
-               _SeasonNumber = value;
+                int? value = _SeasonNumber;
+                GetSeasonNumber(ref value);
+                return (_SeasonNumber = value);
             }
-         }
-      }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+            set
+            {
+                int? oldValue = _SeasonNumber;
+                SetSeasonNumber(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _SeasonNumber = value;
+                }
+            }
+        }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.SeasonMetadata> SeasonMetadata { get; protected set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("SeasonMetadata_SeasonMetadata_Id")]
+        public virtual ICollection<SeasonMetadata> SeasonMetadata { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Episode> Episodes { get; protected set; }
+        [ForeignKey("Episode_Episodes_Id")]
+        public virtual ICollection<Episode> Episodes { get; protected set; }
 
-   }
+    }
 }
 

+ 94 - 111
Jellyfin.Data/Entities/SeasonMetadata.cs

@@ -1,123 +1,106 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class SeasonMetadata: global::Jellyfin.Data.Entities.Metadata
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected SeasonMetadata(): base()
-      {
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static SeasonMetadata CreateSeasonMetadataUnsafe()
-      {
-         return new SeasonMetadata();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_season0"></param>
-      public SeasonMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Season _season0)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
-
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
-
-         if (_season0 == null) throw new ArgumentNullException(nameof(_season0));
-         _season0.SeasonMetadata.Add(this);
-
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_season0"></param>
-      public static SeasonMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Season _season0)
-      {
-         return new SeasonMetadata(title, language, dateadded, datemodified, _season0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Outline
-      /// </summary>
-      protected string _Outline;
-      /// <summary>
-      /// When provided in a partial class, allows value of Outline to be changed before setting.
-      /// </summary>
-      partial void SetOutline(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Outline to be changed before returning.
-      /// </summary>
-      partial void GetOutline(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Outline
-      {
-         get
-         {
-            string value = _Outline;
-            GetOutline(ref value);
-            return (_Outline = value);
-         }
-         set
-         {
-            string oldValue = _Outline;
-            SetOutline(oldValue, ref value);
-            if (oldValue != value)
+    public partial class SeasonMetadata : Metadata
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected SeasonMetadata()
+        {
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static SeasonMetadata CreateSeasonMetadataUnsafe()
+        {
+            return new SeasonMetadata();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_season0"></param>
+        public SeasonMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Season _season0)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
+
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
+
+            if (_season0 == null) throw new ArgumentNullException(nameof(_season0));
+            _season0.SeasonMetadata.Add(this);
+
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_season0"></param>
+        public static SeasonMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Season _season0)
+        {
+            return new SeasonMetadata(title, language, dateadded, datemodified, _season0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Outline
+        /// </summary>
+        protected string _Outline;
+        /// <summary>
+        /// When provided in a partial class, allows value of Outline to be changed before setting.
+        /// </summary>
+        partial void SetOutline(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Outline to be changed before returning.
+        /// </summary>
+        partial void GetOutline(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Outline
+        {
+            get
+            {
+                string value = _Outline;
+                GetOutline(ref value);
+                return (_Outline = value);
+            }
+            set
             {
-               _Outline = value;
+                string oldValue = _Outline;
+                SetOutline(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Outline = value;
+                }
             }
-         }
-      }
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 150 - 166
Jellyfin.Data/Entities/Series.cs

@@ -1,183 +1,167 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Series: global::Jellyfin.Data.Entities.LibraryItem
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Series(): base()
-      {
-         SeriesMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.SeriesMetadata>();
-         Seasons = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Season>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Series CreateSeriesUnsafe()
-      {
-         return new Series();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public Series(Guid urlid, DateTime dateadded)
-      {
-         this.UrlId = urlid;
-
-         this.SeriesMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.SeriesMetadata>();
-         this.Seasons = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Season>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      public static Series Create(Guid urlid, DateTime dateadded)
-      {
-         return new Series(urlid, dateadded);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for AirsDayOfWeek
-      /// </summary>
-      protected global::Jellyfin.Data.Enums.Weekday? _AirsDayOfWeek;
-      /// <summary>
-      /// When provided in a partial class, allows value of AirsDayOfWeek to be changed before setting.
-      /// </summary>
-      partial void SetAirsDayOfWeek(global::Jellyfin.Data.Enums.Weekday? oldValue, ref global::Jellyfin.Data.Enums.Weekday? newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of AirsDayOfWeek to be changed before returning.
-      /// </summary>
-      partial void GetAirsDayOfWeek(ref global::Jellyfin.Data.Enums.Weekday? result);
-
-      public global::Jellyfin.Data.Enums.Weekday? AirsDayOfWeek
-      {
-         get
-         {
-            global::Jellyfin.Data.Enums.Weekday? value = _AirsDayOfWeek;
-            GetAirsDayOfWeek(ref value);
-            return (_AirsDayOfWeek = value);
-         }
-         set
-         {
-            global::Jellyfin.Data.Enums.Weekday? oldValue = _AirsDayOfWeek;
-            SetAirsDayOfWeek(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Series : LibraryItem
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Series()
+        {
+            SeriesMetadata = new HashSet<SeriesMetadata>();
+            Seasons = new HashSet<Season>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Series CreateSeriesUnsafe()
+        {
+            return new Series();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public Series(Guid urlid, DateTime dateadded)
+        {
+            this.UrlId = urlid;
+
+            this.SeriesMetadata = new HashSet<SeriesMetadata>();
+            this.Seasons = new HashSet<Season>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        public static Series Create(Guid urlid, DateTime dateadded)
+        {
+            return new Series(urlid, dateadded);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for AirsDayOfWeek
+        /// </summary>
+        protected Enums.Weekday? _AirsDayOfWeek;
+        /// <summary>
+        /// When provided in a partial class, allows value of AirsDayOfWeek to be changed before setting.
+        /// </summary>
+        partial void SetAirsDayOfWeek(Enums.Weekday? oldValue, ref Enums.Weekday? newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of AirsDayOfWeek to be changed before returning.
+        /// </summary>
+        partial void GetAirsDayOfWeek(ref Enums.Weekday? result);
+
+        public Enums.Weekday? AirsDayOfWeek
+        {
+            get
             {
-               _AirsDayOfWeek = value;
+                Enums.Weekday? value = _AirsDayOfWeek;
+                GetAirsDayOfWeek(ref value);
+                return (_AirsDayOfWeek = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for AirsTime
-      /// </summary>
-      protected DateTimeOffset? _AirsTime;
-      /// <summary>
-      /// When provided in a partial class, allows value of AirsTime to be changed before setting.
-      /// </summary>
-      partial void SetAirsTime(DateTimeOffset? oldValue, ref DateTimeOffset? newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of AirsTime to be changed before returning.
-      /// </summary>
-      partial void GetAirsTime(ref DateTimeOffset? result);
-
-      /// <summary>
-      /// The time the show airs, ignore the date portion
-      /// </summary>
-      public DateTimeOffset? AirsTime
-      {
-         get
-         {
-            DateTimeOffset? value = _AirsTime;
-            GetAirsTime(ref value);
-            return (_AirsTime = value);
-         }
-         set
-         {
-            DateTimeOffset? oldValue = _AirsTime;
-            SetAirsTime(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _AirsTime = value;
+                Enums.Weekday? oldValue = _AirsDayOfWeek;
+                SetAirsDayOfWeek(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _AirsDayOfWeek = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for FirstAired
-      /// </summary>
-      protected DateTimeOffset? _FirstAired;
-      /// <summary>
-      /// When provided in a partial class, allows value of FirstAired to be changed before setting.
-      /// </summary>
-      partial void SetFirstAired(DateTimeOffset? oldValue, ref DateTimeOffset? newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of FirstAired to be changed before returning.
-      /// </summary>
-      partial void GetFirstAired(ref DateTimeOffset? result);
-
-      public DateTimeOffset? FirstAired
-      {
-         get
-         {
-            DateTimeOffset? value = _FirstAired;
-            GetFirstAired(ref value);
-            return (_FirstAired = value);
-         }
-         set
-         {
-            DateTimeOffset? oldValue = _FirstAired;
-            SetFirstAired(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for AirsTime
+        /// </summary>
+        protected DateTimeOffset? _AirsTime;
+        /// <summary>
+        /// When provided in a partial class, allows value of AirsTime to be changed before setting.
+        /// </summary>
+        partial void SetAirsTime(DateTimeOffset? oldValue, ref DateTimeOffset? newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of AirsTime to be changed before returning.
+        /// </summary>
+        partial void GetAirsTime(ref DateTimeOffset? result);
+
+        /// <summary>
+        /// The time the show airs, ignore the date portion
+        /// </summary>
+        public DateTimeOffset? AirsTime
+        {
+            get
             {
-               _FirstAired = value;
+                DateTimeOffset? value = _AirsTime;
+                GetAirsTime(ref value);
+                return (_AirsTime = value);
             }
-         }
-      }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+            set
+            {
+                DateTimeOffset? oldValue = _AirsTime;
+                SetAirsTime(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _AirsTime = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for FirstAired
+        /// </summary>
+        protected DateTimeOffset? _FirstAired;
+        /// <summary>
+        /// When provided in a partial class, allows value of FirstAired to be changed before setting.
+        /// </summary>
+        partial void SetFirstAired(DateTimeOffset? oldValue, ref DateTimeOffset? newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of FirstAired to be changed before returning.
+        /// </summary>
+        partial void GetFirstAired(ref DateTimeOffset? result);
+
+        public DateTimeOffset? FirstAired
+        {
+            get
+            {
+                DateTimeOffset? value = _FirstAired;
+                GetFirstAired(ref value);
+                return (_FirstAired = value);
+            }
+            set
+            {
+                DateTimeOffset? oldValue = _FirstAired;
+                SetFirstAired(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _FirstAired = value;
+                }
+            }
+        }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.SeriesMetadata> SeriesMetadata { get; protected set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("SeriesMetadata_SeriesMetadata_Id")]
+        public virtual ICollection<SeriesMetadata> SeriesMetadata { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Season> Seasons { get; protected set; }
+        [ForeignKey("Season_Seasons_Id")]
+        public virtual ICollection<Season> Seasons { get; protected set; }
 
-   }
+    }
 }
 

+ 204 - 220
Jellyfin.Data/Entities/SeriesMetadata.cs

@@ -1,239 +1,223 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class SeriesMetadata: global::Jellyfin.Data.Entities.Metadata
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected SeriesMetadata(): base()
-      {
-         Networks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static SeriesMetadata CreateSeriesMetadataUnsafe()
-      {
-         return new SeriesMetadata();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_series0"></param>
-      public SeriesMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Series _series0)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
-
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
-
-         if (_series0 == null) throw new ArgumentNullException(nameof(_series0));
-         _series0.SeriesMetadata.Add(this);
-
-         this.Networks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_series0"></param>
-      public static SeriesMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Series _series0)
-      {
-         return new SeriesMetadata(title, language, dateadded, datemodified, _series0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for Outline
-      /// </summary>
-      protected string _Outline;
-      /// <summary>
-      /// When provided in a partial class, allows value of Outline to be changed before setting.
-      /// </summary>
-      partial void SetOutline(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Outline to be changed before returning.
-      /// </summary>
-      partial void GetOutline(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Outline
-      {
-         get
-         {
-            string value = _Outline;
-            GetOutline(ref value);
-            return (_Outline = value);
-         }
-         set
-         {
-            string oldValue = _Outline;
-            SetOutline(oldValue, ref value);
-            if (oldValue != value)
+    public partial class SeriesMetadata : Metadata
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected SeriesMetadata()
+        {
+            Networks = new HashSet<Company>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static SeriesMetadata CreateSeriesMetadataUnsafe()
+        {
+            return new SeriesMetadata();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_series0"></param>
+        public SeriesMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Series _series0)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
+
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
+
+            if (_series0 == null) throw new ArgumentNullException(nameof(_series0));
+            _series0.SeriesMetadata.Add(this);
+
+            this.Networks = new HashSet<Company>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_series0"></param>
+        public static SeriesMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Series _series0)
+        {
+            return new SeriesMetadata(title, language, dateadded, datemodified, _series0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for Outline
+        /// </summary>
+        protected string _Outline;
+        /// <summary>
+        /// When provided in a partial class, allows value of Outline to be changed before setting.
+        /// </summary>
+        partial void SetOutline(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Outline to be changed before returning.
+        /// </summary>
+        partial void GetOutline(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Outline
+        {
+            get
             {
-               _Outline = value;
+                string value = _Outline;
+                GetOutline(ref value);
+                return (_Outline = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Plot
-      /// </summary>
-      protected string _Plot;
-      /// <summary>
-      /// When provided in a partial class, allows value of Plot to be changed before setting.
-      /// </summary>
-      partial void SetPlot(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Plot to be changed before returning.
-      /// </summary>
-      partial void GetPlot(ref string result);
-
-      /// <summary>
-      /// Max length = 65535
-      /// </summary>
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string Plot
-      {
-         get
-         {
-            string value = _Plot;
-            GetPlot(ref value);
-            return (_Plot = value);
-         }
-         set
-         {
-            string oldValue = _Plot;
-            SetPlot(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Plot = value;
+                string oldValue = _Outline;
+                SetOutline(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Outline = value;
+                }
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Tagline
-      /// </summary>
-      protected string _Tagline;
-      /// <summary>
-      /// When provided in a partial class, allows value of Tagline to be changed before setting.
-      /// </summary>
-      partial void SetTagline(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Tagline to be changed before returning.
-      /// </summary>
-      partial void GetTagline(ref string result);
-
-      /// <summary>
-      /// Max length = 1024
-      /// </summary>
-      [MaxLength(1024)]
-      [StringLength(1024)]
-      public string Tagline
-      {
-         get
-         {
-            string value = _Tagline;
-            GetTagline(ref value);
-            return (_Tagline = value);
-         }
-         set
-         {
-            string oldValue = _Tagline;
-            SetTagline(oldValue, ref value);
-            if (oldValue != value)
+        }
+
+        /// <summary>
+        /// Backing field for Plot
+        /// </summary>
+        protected string _Plot;
+        /// <summary>
+        /// When provided in a partial class, allows value of Plot to be changed before setting.
+        /// </summary>
+        partial void SetPlot(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Plot to be changed before returning.
+        /// </summary>
+        partial void GetPlot(ref string result);
+
+        /// <summary>
+        /// Max length = 65535
+        /// </summary>
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string Plot
+        {
+            get
             {
-               _Tagline = value;
+                string value = _Plot;
+                GetPlot(ref value);
+                return (_Plot = value);
             }
-         }
-      }
-
-      /// <summary>
-      /// Backing field for Country
-      /// </summary>
-      protected string _Country;
-      /// <summary>
-      /// When provided in a partial class, allows value of Country to be changed before setting.
-      /// </summary>
-      partial void SetCountry(string oldValue, ref string newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of Country to be changed before returning.
-      /// </summary>
-      partial void GetCountry(ref string result);
-
-      /// <summary>
-      /// Max length = 2
-      /// </summary>
-      [MaxLength(2)]
-      [StringLength(2)]
-      public string Country
-      {
-         get
-         {
-            string value = _Country;
-            GetCountry(ref value);
-            return (_Country = value);
-         }
-         set
-         {
-            string oldValue = _Country;
-            SetCountry(oldValue, ref value);
-            if (oldValue != value)
+            set
             {
-               _Country = value;
+                string oldValue = _Plot;
+                SetPlot(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Plot = value;
+                }
             }
-         }
-      }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        }
+
+        /// <summary>
+        /// Backing field for Tagline
+        /// </summary>
+        protected string _Tagline;
+        /// <summary>
+        /// When provided in a partial class, allows value of Tagline to be changed before setting.
+        /// </summary>
+        partial void SetTagline(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Tagline to be changed before returning.
+        /// </summary>
+        partial void GetTagline(ref string result);
+
+        /// <summary>
+        /// Max length = 1024
+        /// </summary>
+        [MaxLength(1024)]
+        [StringLength(1024)]
+        public string Tagline
+        {
+            get
+            {
+                string value = _Tagline;
+                GetTagline(ref value);
+                return (_Tagline = value);
+            }
+            set
+            {
+                string oldValue = _Tagline;
+                SetTagline(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Tagline = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Backing field for Country
+        /// </summary>
+        protected string _Country;
+        /// <summary>
+        /// When provided in a partial class, allows value of Country to be changed before setting.
+        /// </summary>
+        partial void SetCountry(string oldValue, ref string newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of Country to be changed before returning.
+        /// </summary>
+        partial void GetCountry(ref string result);
+
+        /// <summary>
+        /// Max length = 2
+        /// </summary>
+        [MaxLength(2)]
+        [StringLength(2)]
+        public string Country
+        {
+            get
+            {
+                string value = _Country;
+                GetCountry(ref value);
+                return (_Country = value);
+            }
+            set
+            {
+                string oldValue = _Country;
+                SetCountry(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _Country = value;
+                }
+            }
+        }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Company> Networks { get; protected set; }
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("Company_Networks_Id")]
+        public virtual ICollection<Company> Networks { get; protected set; }
 
-   }
+    }
 }
 

+ 98 - 113
Jellyfin.Data/Entities/Track.cs

@@ -1,127 +1,112 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class Track: global::Jellyfin.Data.Entities.LibraryItem
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected Track(): base()
-      {
-         // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
-         TrackMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.TrackMetadata>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static Track CreateTrackUnsafe()
-      {
-         return new Track();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      /// <param name="_musicalbum0"></param>
-      public Track(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0)
-      {
-         // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
-         // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
-
-         this.UrlId = urlid;
-
-         if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0));
-         _musicalbum0.Tracks.Add(this);
-
-         this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
-         this.TrackMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.TrackMetadata>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
-      /// <param name="_musicalbum0"></param>
-      public static Track Create(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0)
-      {
-         return new Track(urlid, dateadded, _musicalbum0);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Backing field for TrackNumber
-      /// </summary>
-      protected int? _TrackNumber;
-      /// <summary>
-      /// When provided in a partial class, allows value of TrackNumber to be changed before setting.
-      /// </summary>
-      partial void SetTrackNumber(int? oldValue, ref int? newValue);
-      /// <summary>
-      /// When provided in a partial class, allows value of TrackNumber to be changed before returning.
-      /// </summary>
-      partial void GetTrackNumber(ref int? result);
-
-      public int? TrackNumber
-      {
-         get
-         {
-            int? value = _TrackNumber;
-            GetTrackNumber(ref value);
-            return (_TrackNumber = value);
-         }
-         set
-         {
-            int? oldValue = _TrackNumber;
-            SetTrackNumber(oldValue, ref value);
-            if (oldValue != value)
+    public partial class Track : LibraryItem
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected Track()
+        {
+            // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            Releases = new HashSet<Release>();
+            TrackMetadata = new HashSet<TrackMetadata>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static Track CreateTrackUnsafe()
+        {
+            return new Track();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        /// <param name="_musicalbum0"></param>
+        public Track(Guid urlid, DateTime dateadded, MusicAlbum _musicalbum0)
+        {
+            // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
+            // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
+
+            this.UrlId = urlid;
+
+            if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0));
+            _musicalbum0.Tracks.Add(this);
+
+            this.Releases = new HashSet<Release>();
+            this.TrackMetadata = new HashSet<TrackMetadata>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
+        /// <param name="_musicalbum0"></param>
+        public static Track Create(Guid urlid, DateTime dateadded, MusicAlbum _musicalbum0)
+        {
+            return new Track(urlid, dateadded, _musicalbum0);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Backing field for TrackNumber
+        /// </summary>
+        protected int? _TrackNumber;
+        /// <summary>
+        /// When provided in a partial class, allows value of TrackNumber to be changed before setting.
+        /// </summary>
+        partial void SetTrackNumber(int? oldValue, ref int? newValue);
+        /// <summary>
+        /// When provided in a partial class, allows value of TrackNumber to be changed before returning.
+        /// </summary>
+        partial void GetTrackNumber(ref int? result);
+
+        public int? TrackNumber
+        {
+            get
+            {
+                int? value = _TrackNumber;
+                GetTrackNumber(ref value);
+                return (_TrackNumber = value);
+            }
+            set
             {
-               _TrackNumber = value;
+                int? oldValue = _TrackNumber;
+                SetTrackNumber(oldValue, ref value);
+                if (oldValue != value)
+                {
+                    _TrackNumber = value;
+                }
             }
-         }
-      }
+        }
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
+        [ForeignKey("Release_Releases_Id")]
+        public virtual ICollection<Release> Releases { get; protected set; }
 
-      public virtual ICollection<global::Jellyfin.Data.Entities.TrackMetadata> TrackMetadata { get; protected set; }
+        [ForeignKey("TrackMetadata_TrackMetadata_Id")]
+        public virtual ICollection<TrackMetadata> TrackMetadata { get; protected set; }
 
-   }
+    }
 }
 

+ 50 - 68
Jellyfin.Data/Entities/TrackMetadata.cs

@@ -1,86 +1,68 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class TrackMetadata: global::Jellyfin.Data.Entities.Metadata
-   {
-      partial void Init();
+    public partial class TrackMetadata : Metadata
+    {
+        partial void Init();
 
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected TrackMetadata(): base()
-      {
-         Init();
-      }
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected TrackMetadata()
+        {
+            Init();
+        }
 
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static TrackMetadata CreateTrackMetadataUnsafe()
-      {
-         return new TrackMetadata();
-      }
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static TrackMetadata CreateTrackMetadataUnsafe()
+        {
+            return new TrackMetadata();
+        }
 
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_track0"></param>
-      public TrackMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Track _track0)
-      {
-         if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
-         this.Title = title;
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_track0"></param>
+        public TrackMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Track _track0)
+        {
+            if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
+            this.Title = title;
 
-         if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
-         this.Language = language;
+            if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
+            this.Language = language;
 
-         if (_track0 == null) throw new ArgumentNullException(nameof(_track0));
-         _track0.TrackMetadata.Add(this);
+            if (_track0 == null) throw new ArgumentNullException(nameof(_track0));
+            _track0.TrackMetadata.Add(this);
 
 
-         Init();
-      }
+            Init();
+        }
 
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="title">The title or name of the object</param>
-      /// <param name="language">ISO-639-3 3-character language codes</param>
-      /// <param name="_track0"></param>
-      public static TrackMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Track _track0)
-      {
-         return new TrackMetadata(title, language, dateadded, datemodified, _track0);
-      }
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="title">The title or name of the object</param>
+        /// <param name="language">ISO-639-3 3-character language codes</param>
+        /// <param name="_track0"></param>
+        public static TrackMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Track _track0)
+        {
+            return new TrackMetadata(title, language, dateadded, datemodified, _track0);
+        }
 
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
 
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
 
-   }
+    }
 }
 

+ 226 - 233
Jellyfin.Data/Entities/User.cs

@@ -1,242 +1,235 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
 using System;
 using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
-using System.Linq;
-using System.Runtime.CompilerServices;
 
 namespace Jellyfin.Data.Entities
 {
-   public partial class User
-   {
-      partial void Init();
-
-      /// <summary>
-      /// Default constructor. Protected due to required properties, but present because EF needs it.
-      /// </summary>
-      protected User()
-      {
-         Groups = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Group>();
-         Permissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>();
-         ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>();
-         Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
-      /// </summary>
-      public static User CreateUserUnsafe()
-      {
-         return new User();
-      }
-
-      /// <summary>
-      /// Public constructor with required data
-      /// </summary>
-      /// <param name="username"></param>
-      /// <param name="mustupdatepassword"></param>
-      /// <param name="audiolanguagepreference"></param>
-      /// <param name="authenticationproviderid"></param>
-      /// <param name="invalidloginattemptcount"></param>
-      /// <param name="subtitlemode"></param>
-      /// <param name="playdefaultaudiotrack"></param>
-      public User(string username, bool mustupdatepassword, string audiolanguagepreference, string authenticationproviderid, int invalidloginattemptcount, string subtitlemode, bool playdefaultaudiotrack)
-      {
-         if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username));
-         this.Username = username;
-
-         this.MustUpdatePassword = mustupdatepassword;
-
-         if (string.IsNullOrEmpty(audiolanguagepreference)) throw new ArgumentNullException(nameof(audiolanguagepreference));
-         this.AudioLanguagePreference = audiolanguagepreference;
-
-         if (string.IsNullOrEmpty(authenticationproviderid)) throw new ArgumentNullException(nameof(authenticationproviderid));
-         this.AuthenticationProviderId = authenticationproviderid;
-
-         this.InvalidLoginAttemptCount = invalidloginattemptcount;
-
-         if (string.IsNullOrEmpty(subtitlemode)) throw new ArgumentNullException(nameof(subtitlemode));
-         this.SubtitleMode = subtitlemode;
-
-         this.PlayDefaultAudioTrack = playdefaultaudiotrack;
-
-         this.Groups = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Group>();
-         this.Permissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>();
-         this.ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>();
-         this.Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>();
-
-         Init();
-      }
-
-      /// <summary>
-      /// Static create function (for use in LINQ queries, etc.)
-      /// </summary>
-      /// <param name="username"></param>
-      /// <param name="mustupdatepassword"></param>
-      /// <param name="audiolanguagepreference"></param>
-      /// <param name="authenticationproviderid"></param>
-      /// <param name="invalidloginattemptcount"></param>
-      /// <param name="subtitlemode"></param>
-      /// <param name="playdefaultaudiotrack"></param>
-      public static User Create(string username, bool mustupdatepassword, string audiolanguagepreference, string authenticationproviderid, int invalidloginattemptcount, string subtitlemode, bool playdefaultaudiotrack)
-      {
-         return new User(username, mustupdatepassword, audiolanguagepreference, authenticationproviderid, invalidloginattemptcount, subtitlemode, playdefaultaudiotrack);
-      }
-
-      /*************************************************************************
-       * Properties
-       *************************************************************************/
-
-      /// <summary>
-      /// Identity, Indexed, Required
-      /// </summary>
-      [Key]
-      [Required]
-      public Guid Id { get; protected set; }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [ConcurrencyCheck]
-      [Required]
-      public byte[] LastLoginTimestamp { get; set; }
-
-      /// <summary>
-      /// Required, Max length = 255
-      /// </summary>
-      [Required]
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string Username { get; set; }
-
-      /// <summary>
-      /// Max length = 65535
-      /// </summary>
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string Password { get; set; }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public bool MustUpdatePassword { get; set; }
-
-      /// <summary>
-      /// Required, Max length = 255
-      /// </summary>
-      [Required]
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string AudioLanguagePreference { get; set; }
-
-      /// <summary>
-      /// Required, Max length = 255
-      /// </summary>
-      [Required]
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string AuthenticationProviderId { get; set; }
-
-      /// <summary>
-      /// Max length = 65535
-      /// </summary>
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string GroupedFolders { get; set; }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public int InvalidLoginAttemptCount { get; set; }
-
-      /// <summary>
-      /// Max length = 65535
-      /// </summary>
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string LatestItemExcludes { get; set; }
-
-      public int? LoginAttemptsBeforeLockout { get; set; }
-
-      /// <summary>
-      /// Max length = 65535
-      /// </summary>
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string MyMediaExcludes { get; set; }
-
-      /// <summary>
-      /// Max length = 65535
-      /// </summary>
-      [MaxLength(65535)]
-      [StringLength(65535)]
-      public string OrderedViews { get; set; }
-
-      /// <summary>
-      /// Required, Max length = 255
-      /// </summary>
-      [Required]
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string SubtitleMode { get; set; }
-
-      /// <summary>
-      /// Required
-      /// </summary>
-      [Required]
-      public bool PlayDefaultAudioTrack { get; set; }
-
-      /// <summary>
-      /// Max length = 255
-      /// </summary>
-      [MaxLength(255)]
-      [StringLength(255)]
-      public string SubtitleLanguagePrefernce { get; set; }
-
-      public bool? DisplayMissingEpisodes { get; set; }
-
-      public bool? DisplayCollectionsView { get; set; }
-
-      public bool? HidePlayedInLatest { get; set; }
-
-      public bool? RememberAudioSelections { get; set; }
-
-      public bool? RememberSubtitleSelections { get; set; }
-
-      public bool? EnableNextEpisodeAutoPlay { get; set; }
-
-      public bool? EnableUserPreferenceAccess { get; set; }
-
-      /*************************************************************************
-       * Navigation properties
-       *************************************************************************/
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.Group> Groups { get; protected set; }
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.Permission> Permissions { get; protected set; }
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.ProviderMapping> ProviderMappings { get; protected set; }
-
-      public virtual ICollection<global::Jellyfin.Data.Entities.Preference> Preferences { get; protected set; }
-
-   }
+    public partial class User
+    {
+        partial void Init();
+
+        /// <summary>
+        /// Default constructor. Protected due to required properties, but present because EF needs it.
+        /// </summary>
+        protected User()
+        {
+            Groups = new HashSet<Group>();
+            Permissions = new HashSet<Permission>();
+            ProviderMappings = new HashSet<ProviderMapping>();
+            Preferences = new HashSet<Preference>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
+        /// </summary>
+        public static User CreateUserUnsafe()
+        {
+            return new User();
+        }
+
+        /// <summary>
+        /// Public constructor with required data
+        /// </summary>
+        /// <param name="username"></param>
+        /// <param name="mustupdatepassword"></param>
+        /// <param name="audiolanguagepreference"></param>
+        /// <param name="authenticationproviderid"></param>
+        /// <param name="invalidloginattemptcount"></param>
+        /// <param name="subtitlemode"></param>
+        /// <param name="playdefaultaudiotrack"></param>
+        public User(string username, bool mustupdatepassword, string audiolanguagepreference, string authenticationproviderid, int invalidloginattemptcount, string subtitlemode, bool playdefaultaudiotrack)
+        {
+            if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username));
+            this.Username = username;
+
+            this.MustUpdatePassword = mustupdatepassword;
+
+            if (string.IsNullOrEmpty(audiolanguagepreference)) throw new ArgumentNullException(nameof(audiolanguagepreference));
+            this.AudioLanguagePreference = audiolanguagepreference;
+
+            if (string.IsNullOrEmpty(authenticationproviderid)) throw new ArgumentNullException(nameof(authenticationproviderid));
+            this.AuthenticationProviderId = authenticationproviderid;
+
+            this.InvalidLoginAttemptCount = invalidloginattemptcount;
+
+            if (string.IsNullOrEmpty(subtitlemode)) throw new ArgumentNullException(nameof(subtitlemode));
+            this.SubtitleMode = subtitlemode;
+
+            this.PlayDefaultAudioTrack = playdefaultaudiotrack;
+
+            this.Groups = new HashSet<Group>();
+            this.Permissions = new HashSet<Permission>();
+            this.ProviderMappings = new HashSet<ProviderMapping>();
+            this.Preferences = new HashSet<Preference>();
+
+            Init();
+        }
+
+        /// <summary>
+        /// Static create function (for use in LINQ queries, etc.)
+        /// </summary>
+        /// <param name="username"></param>
+        /// <param name="mustupdatepassword"></param>
+        /// <param name="audiolanguagepreference"></param>
+        /// <param name="authenticationproviderid"></param>
+        /// <param name="invalidloginattemptcount"></param>
+        /// <param name="subtitlemode"></param>
+        /// <param name="playdefaultaudiotrack"></param>
+        public static User Create(string username, bool mustupdatepassword, string audiolanguagepreference, string authenticationproviderid, int invalidloginattemptcount, string subtitlemode, bool playdefaultaudiotrack)
+        {
+            return new User(username, mustupdatepassword, audiolanguagepreference, authenticationproviderid, invalidloginattemptcount, subtitlemode, playdefaultaudiotrack);
+        }
+
+        /*************************************************************************
+         * Properties
+         *************************************************************************/
+
+        /// <summary>
+        /// Identity, Indexed, Required
+        /// </summary>
+        [Key]
+        [Required]
+        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+        public int Id { get; protected set; }
+
+        /// <summary>
+        /// Required, Max length = 255
+        /// </summary>
+        [Required]
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string Username { get; set; }
+
+        /// <summary>
+        /// Max length = 65535
+        /// </summary>
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string Password { get; set; }
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public bool MustUpdatePassword { get; set; }
+
+        /// <summary>
+        /// Required, Max length = 255
+        /// </summary>
+        [Required]
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string AudioLanguagePreference { get; set; }
+
+        /// <summary>
+        /// Required, Max length = 255
+        /// </summary>
+        [Required]
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string AuthenticationProviderId { get; set; }
+
+        /// <summary>
+        /// Max length = 65535
+        /// </summary>
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string GroupedFolders { get; set; }
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public int InvalidLoginAttemptCount { get; set; }
+
+        /// <summary>
+        /// Max length = 65535
+        /// </summary>
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string LatestItemExcludes { get; set; }
+
+        public int? LoginAttemptsBeforeLockout { get; set; }
+
+        /// <summary>
+        /// Max length = 65535
+        /// </summary>
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string MyMediaExcludes { get; set; }
+
+        /// <summary>
+        /// Max length = 65535
+        /// </summary>
+        [MaxLength(65535)]
+        [StringLength(65535)]
+        public string OrderedViews { get; set; }
+
+        /// <summary>
+        /// Required, Max length = 255
+        /// </summary>
+        [Required]
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string SubtitleMode { get; set; }
+
+        /// <summary>
+        /// Required
+        /// </summary>
+        [Required]
+        public bool PlayDefaultAudioTrack { get; set; }
+
+        /// <summary>
+        /// Max length = 255
+        /// </summary>
+        [MaxLength(255)]
+        [StringLength(255)]
+        public string SubtitleLanguagePrefernce { get; set; }
+
+        public bool? DisplayMissingEpisodes { get; set; }
+
+        public bool? DisplayCollectionsView { get; set; }
+
+        public bool? HidePlayedInLatest { get; set; }
+
+        public bool? RememberAudioSelections { get; set; }
+
+        public bool? RememberSubtitleSelections { get; set; }
+
+        public bool? EnableNextEpisodeAutoPlay { get; set; }
+
+        public bool? EnableUserPreferenceAccess { get; set; }
+
+        /// <summary>
+        /// Required, ConcurrenyToken
+        /// </summary>
+        [ConcurrencyCheck]
+        [Required]
+        public uint RowVersion { get; set; }
+
+        public void OnSavingChanges()
+        {
+            RowVersion++;
+        }
+
+        /*************************************************************************
+         * Navigation properties
+         *************************************************************************/
+        [ForeignKey("Group_Groups_Id")]
+        public virtual ICollection<Group> Groups { get; protected set; }
+
+        [ForeignKey("Permission_Permissions_Id")]
+        public virtual ICollection<Permission> Permissions { get; protected set; }
+
+        [ForeignKey("ProviderMapping_ProviderMappings_Id")]
+        public virtual ICollection<ProviderMapping> ProviderMappings { get; protected set; }
+
+        [ForeignKey("Preference_Preferences_Id")]
+        public virtual ICollection<Preference> Preferences { get; protected set; }
+
+    }
 }
 

+ 8 - 22
Jellyfin.Data/Enums/ArtKind.cs

@@ -1,25 +1,11 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-using System;
-
 namespace Jellyfin.Data.Enums
 {
-   public enum ArtKind : Int32
-   {
-      Other,
-      Poster,
-      Banner,
-      Thumbnail,
-      Logo
-   }
+    public enum ArtKind
+    {
+        Other,
+        Poster,
+        Banner,
+        Thumbnail,
+        Logo
+    }
 }

+ 8 - 22
Jellyfin.Data/Enums/MediaFileKind.cs

@@ -1,25 +1,11 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-using System;
-
 namespace Jellyfin.Data.Enums
 {
-   public enum MediaFileKind : Int32
-   {
-      Main,
-      Sidecar,
-      AdditionalPart,
-      AlternativeFormat,
-      AdditionalStream
-   }
+    public enum MediaFileKind
+    {
+        Main,
+        Sidecar,
+        AdditionalPart,
+        AlternativeFormat,
+        AdditionalStream
+    }
 }

+ 26 - 0
Jellyfin.Data/Enums/PermissionKind.cs

@@ -0,0 +1,26 @@
+namespace Jellyfin.Data.Enums
+{
+    public enum PermissionKind
+    {
+        IsAdministrator,
+        IsHidden,
+        IsDisabled,
+        BlockUnrateditems,
+        EnbleSharedDeviceControl,
+        EnableRemoteAccess,
+        EnableLiveTvManagement,
+        EnableLiveTvAccess,
+        EnableMediaPlayback,
+        EnableAudioPlaybackTranscoding,
+        EnableVideoPlaybackTranscoding,
+        EnableContentDeletion,
+        EnableContentDownloading,
+        EnableSyncTranscoding,
+        EnableMediaConversion,
+        EnableAllDevices,
+        EnableAllChannels,
+        EnableAllFolders,
+        EnablePublicSharing,
+        AccessSchedules
+    }
+}

+ 15 - 29
Jellyfin.Data/Enums/PersonRoleType.cs

@@ -1,32 +1,18 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-using System;
-
 namespace Jellyfin.Data.Enums
 {
-   public enum PersonRoleType : Int32
-   {
-      Other,
-      Director,
-      Artist,
-      OriginalArtist,
-      Actor,
-      VoiceActor,
-      Producer,
-      Remixer,
-      Conductor,
-      Composer,
-      Author,
-      Editor
-   }
+    public enum PersonRoleType
+    {
+        Other,
+        Director,
+        Artist,
+        OriginalArtist,
+        Actor,
+        VoiceActor,
+        Producer,
+        Remixer,
+        Conductor,
+        Composer,
+        Author,
+        Editor
+    }
 }

+ 13 - 0
Jellyfin.Data/Enums/PreferenceKind.cs

@@ -0,0 +1,13 @@
+namespace Jellyfin.Data.Enums
+{
+    public enum PreferenceKind
+    {
+        MaxParentalRating,
+        BlockedTags,
+        RemoteClientBitrateLimit,
+        EnabledDevices,
+        EnabledChannels,
+        EnabledFolders,
+        EnableContentDeletionFromFolders
+    }
+}

+ 10 - 24
Jellyfin.Data/Enums/Weekday.cs

@@ -1,27 +1,13 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated from a template.
-//
-//     Manual changes to this file may cause unexpected behavior in your application.
-//     Manual changes to this file will be overwritten if the code is regenerated.
-//
-//     Produced by Entity Framework Visual Editor
-//     https://github.com/msawczyn/EFDesigner
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-using System;
-
 namespace Jellyfin.Data.Enums
 {
-   public enum Weekday : Int32
-   {
-      Sunday,
-      Monday,
-      Tuesday,
-      Wednesday,
-      Thursday,
-      Friday,
-      Saturday
-   }
+    public enum Weekday
+    {
+        Sunday,
+        Monday,
+        Tuesday,
+        Wednesday,
+        Thursday,
+        Friday,
+        Saturday
+    }
 }

+ 9 - 0
Jellyfin.Data/ISavingChanges.cs

@@ -0,0 +1,9 @@
+#pragma warning disable CS1591
+
+namespace Jellyfin.Data
+{
+    public interface ISavingChanges
+    {
+        void OnSavingChanges();
+    }
+}

+ 0 - 0
Jellyfin.Data/Structs/.gitkeep


+ 34 - 0
Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj

@@ -0,0 +1,34 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+    <GenerateDocumentationFile>true</GenerateDocumentationFile>
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+
+  <!-- Code analysers-->
+  <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
+    <PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
+    <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
+    <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Compile Include="..\SharedVersion.cs" />
+    <Compile Remove="Migrations\20200430214405_InitialSchema.cs" />
+    <Compile Remove="Migrations\20200430214405_InitialSchema.Designer.cs" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Jellyfin.Data\Jellyfin.Data.csproj" />
+    <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
+    <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
+  </ItemGroup>
+
+</Project>

+ 115 - 0
Jellyfin.Server.Implementations/JellyfinDb.cs

@@ -0,0 +1,115 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1201 // Constuctors should not follow properties
+#pragma warning disable SA1516 // Elements should be followed by a blank line
+#pragma warning disable SA1623 // Property's documentation should begin with gets or sets
+#pragma warning disable SA1629 // Documentation should end with a period
+#pragma warning disable SA1648 // Inheritdoc should be used with inheriting class
+
+using System.Linq;
+using Jellyfin.Data;
+using Jellyfin.Data.Entities;
+using Microsoft.EntityFrameworkCore;
+
+namespace Jellyfin.Server.Implementations
+{
+    /// <inheritdoc/>
+    public partial class JellyfinDb : DbContext
+    {
+        /*public virtual DbSet<Artwork> Artwork { get; set; }
+        public virtual DbSet<Book> Books { get; set; }
+        public virtual DbSet<BookMetadata> BookMetadata { get; set; }
+        public virtual DbSet<Chapter> Chapters { get; set; }
+        public virtual DbSet<Collection> Collections { get; set; }
+        public virtual DbSet<CollectionItem> CollectionItems { get; set; }
+        public virtual DbSet<Company> Companies { get; set; }
+        public virtual DbSet<CompanyMetadata> CompanyMetadata { get; set; }
+        public virtual DbSet<CustomItem> CustomItems { get; set; }
+        public virtual DbSet<CustomItemMetadata> CustomItemMetadata { get; set; }
+        public virtual DbSet<Episode> Episodes { get; set; }
+        public virtual DbSet<EpisodeMetadata> EpisodeMetadata { get; set; }
+        public virtual DbSet<Genre> Genres { get; set; }
+        public virtual DbSet<Group> Groups { get; set; }
+        public virtual DbSet<Library> Libraries { get; set; }
+        public virtual DbSet<LibraryItem> LibraryItems { get; set; }
+        public virtual DbSet<LibraryRoot> LibraryRoot { get; set; }
+        public virtual DbSet<MediaFile> MediaFiles { get; set; }
+        public virtual DbSet<MediaFileStream> MediaFileStream { get; set; }
+        public virtual DbSet<Metadata> Metadata { get; set; }
+        public virtual DbSet<MetadataProvider> MetadataProviders { get; set; }
+        public virtual DbSet<MetadataProviderId> MetadataProviderIds { get; set; }
+        public virtual DbSet<Movie> Movies { get; set; }
+        public virtual DbSet<MovieMetadata> MovieMetadata { get; set; }
+        public virtual DbSet<MusicAlbum> MusicAlbums { get; set; }
+        public virtual DbSet<MusicAlbumMetadata> MusicAlbumMetadata { get; set; }
+        public virtual DbSet<Permission> Permissions { get; set; }
+        public virtual DbSet<Person> People { get; set; }
+        public virtual DbSet<PersonRole> PersonRoles { get; set; }
+        public virtual DbSet<Photo> Photo { get; set; }
+        public virtual DbSet<PhotoMetadata> PhotoMetadata { get; set; }
+        public virtual DbSet<Preference> Preferences { get; set; }
+        public virtual DbSet<ProviderMapping> ProviderMappings { get; set; }
+        public virtual DbSet<Rating> Ratings { get; set; }
+        /// <summary>
+        /// Repository for global::Jellyfin.Data.Entities.RatingSource - This is the entity to
+        /// store review ratings, not age ratings
+        /// </summary>
+        public virtual DbSet<RatingSource> RatingSources { get; set; }
+        public virtual DbSet<Release> Releases { get; set; }
+        public virtual DbSet<Season> Seasons { get; set; }
+        public virtual DbSet<SeasonMetadata> SeasonMetadata { get; set; }
+        public virtual DbSet<Series> Series { get; set; }
+        public virtual DbSet<SeriesMetadata> SeriesMetadata { get; set; }
+        public virtual DbSet<Track> Tracks { get; set; }
+        public virtual DbSet<TrackMetadata> TrackMetadata { get; set; }
+        public virtual DbSet<User> Users { get; set; } */
+
+        /// <summary>
+        /// Gets or sets the default connection string.
+        /// </summary>
+        public static string ConnectionString { get; set; } = @"Data Source=jellyfin.db";
+
+        /// <inheritdoc />
+        public JellyfinDb(DbContextOptions<JellyfinDb> options) : base(options)
+        {
+        }
+
+        partial void CustomInit(DbContextOptionsBuilder optionsBuilder);
+
+        /// <inheritdoc />
+        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+        {
+            CustomInit(optionsBuilder);
+        }
+
+        partial void OnModelCreatingImpl(ModelBuilder modelBuilder);
+        partial void OnModelCreatedImpl(ModelBuilder modelBuilder);
+
+        /// <inheritdoc />
+        protected override void OnModelCreating(ModelBuilder modelBuilder)
+        {
+            base.OnModelCreating(modelBuilder);
+            OnModelCreatingImpl(modelBuilder);
+
+            modelBuilder.HasDefaultSchema("jellyfin");
+
+            /*modelBuilder.Entity<Artwork>().HasIndex(t => t.Kind);
+            modelBuilder.Entity<Genre>().HasIndex(t => t.Name)
+                        .IsUnique();
+            modelBuilder.Entity<LibraryItem>().HasIndex(t => t.UrlId)
+                        .IsUnique();*/
+
+            OnModelCreatedImpl(modelBuilder);
+        }
+
+        public override int SaveChanges()
+        {
+            foreach (var entity in ChangeTracker.Entries().Where(e => e.State == EntityState.Modified))
+            {
+                var saveEntity = entity.Entity as ISavingChanges;
+                saveEntity.OnSavingChanges();
+            }
+
+            return base.SaveChanges();
+        }
+    }
+}

+ 1 - 3
Jellyfin.Server/Migrations/IMigrationRoutine.cs

@@ -21,8 +21,6 @@ namespace Jellyfin.Server.Migrations
         /// <summary>
         /// Execute the migration routine.
         /// </summary>
-        /// <param name="host">Host that hosts current version.</param>
-        /// <param name="logger">Host logger.</param>
-        public void Perform(CoreAppHost host, ILogger logger);
+        public void Perform();
     }
 }

+ 12 - 7
Jellyfin.Server/Migrations/MigrationRunner.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Linq;
 using MediaBrowser.Common.Configuration;
+using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 
 namespace Jellyfin.Server.Migrations
@@ -13,10 +14,10 @@ namespace Jellyfin.Server.Migrations
         /// <summary>
         /// The list of known migrations, in order of applicability.
         /// </summary>
-        internal static readonly IMigrationRoutine[] Migrations =
+        private static readonly Type[] _migrationTypes =
         {
-            new Routines.DisableTranscodingThrottling(),
-            new Routines.CreateUserLoggingConfigFile()
+            typeof(Routines.DisableTranscodingThrottling),
+            typeof(Routines.CreateUserLoggingConfigFile)
         };
 
         /// <summary>
@@ -27,6 +28,10 @@ namespace Jellyfin.Server.Migrations
         public static void Run(CoreAppHost host, ILoggerFactory loggerFactory)
         {
             var logger = loggerFactory.CreateLogger<MigrationRunner>();
+            var migrations = _migrationTypes
+                .Select(m => ActivatorUtilities.CreateInstance(host.ServiceProvider, m))
+                .OfType<IMigrationRoutine>()
+                .ToArray();
             var migrationOptions = ((IConfigurationManager)host.ServerConfigurationManager).GetConfiguration<MigrationOptions>(MigrationsListStore.StoreKey);
 
             if (!host.ServerConfigurationManager.Configuration.IsStartupWizardCompleted && migrationOptions.Applied.Count == 0)
@@ -34,16 +39,16 @@ namespace Jellyfin.Server.Migrations
                 // If startup wizard is not finished, this is a fresh install.
                 // Don't run any migrations, just mark all of them as applied.
                 logger.LogInformation("Marking all known migrations as applied because this is a fresh install");
-                migrationOptions.Applied.AddRange(Migrations.Select(m => (m.Id, m.Name)));
+                migrationOptions.Applied.AddRange(migrations.Select(m => (m.Id, m.Name)));
                 host.ServerConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions);
                 return;
             }
 
             var appliedMigrationIds = migrationOptions.Applied.Select(m => m.Id).ToHashSet();
 
-            for (var i = 0; i < Migrations.Length; i++)
+            for (var i = 0; i < migrations.Length; i++)
             {
-                var migrationRoutine = Migrations[i];
+                var migrationRoutine = migrations[i];
                 if (appliedMigrationIds.Contains(migrationRoutine.Id))
                 {
                     logger.LogDebug("Skipping migration '{Name}' since it is already applied", migrationRoutine.Name);
@@ -54,7 +59,7 @@ namespace Jellyfin.Server.Migrations
 
                 try
                 {
-                    migrationRoutine.Perform(host, logger);
+                    migrationRoutine.Perform();
                 }
                 catch (Exception ex)
                 {

部分文件因为文件数量过多而无法显示