diff --git a/Extensions/Xtensive.Orm.Localization.Tests/Model/DictionaryModel.cs b/Extensions/Xtensive.Orm.Localization.Tests/Model/DictionaryModel.cs new file mode 100644 index 0000000000..7d1abfe558 --- /dev/null +++ b/Extensions/Xtensive.Orm.Localization.Tests/Model/DictionaryModel.cs @@ -0,0 +1,58 @@ +// Copyright (C) 2020 Xtensive LLC. +// This code is distributed under MIT license terms. +// See the License.txt file in the project root for more information. + +using System.Globalization; +using Xtensive.Orm.Model; + +namespace Xtensive.Orm.Localization.Tests.Model +{ + [HierarchyRoot(InheritanceSchema = InheritanceSchema.ConcreteTable)] + public abstract class AbstractDictionary : Entity + { + [Key, Field] + public int Id { get; private set; } + + [Field(Nullable = false, Length = 64)] + public string Identifier { get; set; } + + // abstract property + public abstract string Name { get; set; } + + protected AbstractDictionary(Session session) : base(session) { } + } + + public abstract class AbstractLocalizableDictionary : AbstractDictionary, ILocalizable + where T : AbstractLocalizableDictionary + where TT : AbstractDictionaryLocalization + { + public override string Name { get => Localizations.Current.Name; set => Localizations.Current.Name = value; } + + [Field] + public LocalizationSet Localizations { get; private set; } + + protected AbstractLocalizableDictionary(Session session) : base(session) { } + } + + public abstract class AbstractDictionaryLocalization : Localization + where TT : AbstractDictionaryLocalization + where T : AbstractLocalizableDictionary + { + [Field(Nullable = false, Length = 512)] + public string Name { get; set; } + + protected AbstractDictionaryLocalization(Session session, CultureInfo culture, T target) : base(session, culture, target) { } + } + + public class Country : AbstractLocalizableDictionary, ILocalizable + { + public Country(Session session) : base(session) { } + } + + [HierarchyRoot] + public class CountryLocalization : AbstractDictionaryLocalization + { + public CountryLocalization(Session session, CultureInfo culture, Country target) : base(session, culture, target) { } + } + +} diff --git a/Extensions/Xtensive.Orm.Localization.Tests/ProjectionToCustomTypesTests.cs b/Extensions/Xtensive.Orm.Localization.Tests/ProjectionToCustomTypesTests.cs new file mode 100644 index 0000000000..50fdfa3681 --- /dev/null +++ b/Extensions/Xtensive.Orm.Localization.Tests/ProjectionToCustomTypesTests.cs @@ -0,0 +1,56 @@ +// Copyright (C) 2020 Xtensive LLC. +// This code is distributed under MIT license terms. +// See the License.txt file in the project root for more information. + +using System.Linq; +using System.Threading; +using NUnit.Framework; +using Xtensive.Orm.Localization.Tests.Model; + +namespace Xtensive.Orm.Localization.Tests +{ + [TestFixture] + public class ProjectionToCustomTypesTests : AutoBuildTest + { + protected override void PopulateDatabase() + { + using (var session = Domain.OpenSession()) + using (var ts = session.OpenTransaction()) { + // populating database + var m1 = new Country(session) { + Identifier = "HUN", + Name = "Magyarország" + }; + var m2 = new Country(session) { + Identifier = "RUS", + Name = "Oroszország" + }; + using (new LocalizationScope(EnglishCulture)) { + m2.Name = "Russia"; + } + using (new LocalizationScope(SpanishCulture)) { + m2.Name = "Rusia"; + } + ts.Complete(); + } + } + + [Test] + public void EntityHierarchyWithAbstractPropertyTest() + { + Thread.CurrentThread.CurrentCulture = EnglishCulture; + using (var session = Domain.OpenSession()) + using (var ts = session.OpenTransaction()) { + var q = session.Query.All().OrderBy(e => e.Identifier).Select(e => new { e.Name }); + var l = q.ToList(); + // assertions + Assert.AreEqual(2, l.Count); + var propertyInfos = l.First().GetType().GetProperties(); + Assert.AreEqual(propertyInfos.Length, 1); + Assert.AreEqual(propertyInfos.First().Name, nameof(Country.Name)); + Assert.AreEqual(l.First().Name, "Magyarország"); + Assert.AreEqual(l.Last().Name, "Russia"); + } + } + } +} \ No newline at end of file diff --git a/Extensions/Xtensive.Orm.Localization/Internals/LocalizationExpressionVisitor.cs b/Extensions/Xtensive.Orm.Localization/Internals/LocalizationExpressionVisitor.cs index 3c52e71e76..704840ce7e 100644 --- a/Extensions/Xtensive.Orm.Localization/Internals/LocalizationExpressionVisitor.cs +++ b/Extensions/Xtensive.Orm.Localization/Internals/LocalizationExpressionVisitor.cs @@ -25,7 +25,7 @@ protected override Expression VisitMemberAccess(MemberExpression me) if (Map == null) return me; - var localizationInfo = Map.Get(me.Member.ReflectedType); + var localizationInfo = Map.Get(me.Expression?.Type ?? me.Member.ReflectedType); if (localizationInfo == null || !localizationInfo.LocalizationTypeInfo.Fields.Contains(me.Member.Name)) return base.VisitMemberAccess(me);