-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multi Lingual entities new system #1832
Comments
Sample code test results: |
Maybe you can refer to the EF Core mapping of abp/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs Line 366 in 654eeed
|
@maliming Thanks for helpful code line hint public interface ITranslation
{
string Language { get; set; }
}
public interface ITranslatable<TTranslation> where TTranslation : class, ITranslation
{
IDictionary<string, TTranslation> Translations { get; set; }
}
public static class AutoMapExtensions
{
public static CreateMultiLingualMapResult<TTranslatableEntity, TTranslation, TDestination>
CreateTranslatableMap<TTranslatableEntity, TTranslation, TDestination>(
this IMapperConfigurationExpression configuration, MultiLingualMapContext multiLingualMapContext)
where TTranslatableEntity : ITranslatable<TTranslation>
where TTranslation : class, ITranslation
{
return new CreateMultiLingualMapResult<TTranslatableEntity, TTranslation, TDestination>
{
TranslationMap = configuration.CreateMap<TTranslation, TDestination>(),
EntityMap = configuration.CreateMap<TTranslatableEntity, TDestination>().AfterMap(
(source, destination, context) =>
{
if (source.Translations == null)
{
return;
}
if (source.Translations.TryGetValue(CultureInfo.CurrentUICulture.Name,
out TTranslation translation))
{
if (translation != null)
{
context.Mapper.Map(translation, destination, opts => opts.ConfigureMap()
.ForAllMembers(cfg => cfg.Condition((src, dest, srcMember) => srcMember != null)));
return;
}
}
var defaultLanguage = multiLingualMapContext.SettingManager
.GetSettingValue(LocalizationSettingNames.DefaultLanguage);
if (source.Translations.TryGetValue(defaultLanguage, out translation))
{
if (translation != null)
{
context.Mapper.Map(translation, destination, opts => opts.ConfigureMap()
.ForAllMembers(cfg => cfg.Condition((src, dest, srcMember) => srcMember != null)));
return;
}
}
translation = source.Translations.FirstOrDefault().Value;
if (translation != null)
{
context.Mapper.Map(translation, destination, opts => opts.ConfigureMap()
.ForAllMembers(cfg => cfg.Condition((src, dest, srcMember) => srcMember != null)));
}
}
)
};
}
}
protected virtual void ConfigureTranslationsProperty<TTranslatableEntity, TTranslation>(ModelBuilder builder)
where TTranslatableEntity : class, ITranslatable<TTranslation>
where TTranslation : class, ITranslation
{
if (!typeof(ITranslatable<TTranslation>).IsAssignableFrom(typeof(TTranslatableEntity)))
{
return;
}
builder.Entity<TTranslatableEntity>(b =>
{
b.Property(x => ((ITranslatable<TTranslation>) x).Translations)
.HasConversion(
d => d.Count == 0
? null
: JsonConvert.SerializeObject(d, Formatting.None),
s => s == null
? new Dictionary<string, TTranslation>()
: JsonConvert.DeserializeObject<Dictionary<string, TTranslation>>(s)
);
});
} This code works well in ABZ. Is 17 times faster than old-multi-lingual-entity in my ABZ. With this style we can skip additional translations table and we don't need to care about required translatable properties. For who has my problem: <tabset class="tab-container tabbable-line">
<div class="form-group">
<label for="Category_Name">{{l("Name")}} *</label>
<input type="text" id="Category_Name" class="form-control" [(ngModel)]="category.name" name="Name" required />
</div>
<tab *ngFor="let translation of translations; let i=index" customClass="m-tabs__item">
<ng-template tabHeading><i [class]="languages[i].icon"></i>{{languages[i].displayName}}</ng-template>
<div class="form-group">
<label for="Category_DisplayName_{{i}}">{{l("DisplayName")}} *</label>
<input type="text" [required]="i === 0 ? 'required' : null" id="Category_DisplayName_{{i}}" class="form-control" [(ngModel)]="translation.displayName" name="DisplayName_{{i}}" />
</div>
</tab>
</tabset> this.currentLanguage = this.localization.currentLanguage;
this.languages = _.filter(this.localization.languages, l => (l).isDisabled === false);
_.remove(this.languages, lng => lng.name === this.currentLanguage.name);
this.languages.splice(0, 0, this.currentLanguage);
this.category = new CreateOrEditCategoryDto();
this.category.translations = [];
this.category.id = this.categoryId;
for (let lng of this.languages) {
let translation = new CategoryTranslationDto();
translation.language = (lng).name;
this.translations.push(translation);
this.active = true;
} |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
I have some problems on working with Multi lingual entities previous ABP version, where my model has required translatable field and where I need origin input without translation (or default app culture and skip current culture). So, what you think if we do little changes for passing this cases:
The text was updated successfully, but these errors were encountered: