I work on a multilingual site and I have built this structure for my "localizable" entities.
The interfaces:
public interface ILocalizable<T>
where T : ILocalized
{
ICollection<T> Content { get; set; }
}
public interface ILocalized
{
int LanguageId { get; set; }
virtual Language Language { get; set; }
}
And implementation:
public class Entity : ILocalizable<EntityLocalized>
{
public int Id { get; set; }
public ICollection<EntityLocalized> Content { get; set; }
}
public class EntityLocalized : ILocalized
{
public int LanguageId { get; set; }
public virtual Language Language { get; set; }
public int EntityId { get; set; }
public string Title { get; set; }
}
The reason for this is that I could write an extension method that allows me to get the right string this way:
Entity entity; // get entity from database
string localizedString = entity.Content.Translate(localized => localized.Title);
Everything works just fine. I just had an idea to write another extension method that would save me some work while building a query. So that I don't have to write all the time:
IQueryable<Entity> query; // some query
return query.Include(entity => entity.Content.Select(localized => localized.Language));
So I have this:
public static IQueryable<TEntity> WithLocalization<TEntity>(this IQueryable<TEntity> query)
{
return query.Include(entity => entity.Content.Select(content => content.Language));
}
But obviously I need to specify the generic type. This won't compile. I tried everything.
public static IQueryable<TEntity> WithLocalization<TEntity>(this IQueryable<ILocalizable<ILocalized>> set) where TEntity : ILocalizable<ILocalized> {}
IQueryable<Entity> query; // get query
query.WithLocalization(); // intellisense doesn't display and this won't compile
I kind of understand the reason. It's been discussed there many times. I'm just wondering if there's a way how to build such an extension method without a need to explicitly use and pass 2 generics types, like:
public static IQueryable<TEntity> WithLocalization<TEntity, TEntityLocalized>(this IQueryable<TEntity> set)
where TEntityLocalized : ILocalized
where TEntity : ILocalizable<TEntityLocalized> {}
Thank you!
I think you want...
public static IQueryable<ILocalizable<TEntityLocalized>> WithLocalization<TEntityLocalized>(this IQueryable<ILocalizable<TEntityLocalized>> query)
where TEntityLocalized : ILocalized {
return query.Include(entity => entity.Content.Select(content => content.Language));
}
You aren't propagating the TEntity
generic parameter into the signature correctly.
public static IQueryable<ILocalizable<TEntity>> WithLocalization<TEntity>(this IQueryable<ILocalizable<TEntity>> query)
where TEntity : ILocalized
{
return query.Include (entity => entity.Content.Select (content => content.Language));
}
public class Test
{
public Test()
{
IQueryable<Entity> query;
query.WithLocalization ();
}
}
compiles correctly and gives correct intellisense.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.