Skip to content

Commit 6c5e260

Browse files
Ihar YakimushIhar Yakimush
authored andcommitted
customize mapping manager
1 parent 4d0d7a1 commit 6c5e260

File tree

8 files changed

+46
-9
lines changed

8 files changed

+46
-9
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ SolrNet IQueryable provider. Extend SolrNet functionality by adding limited LINQ
33

44
## Code Sample
55
### Prerequisites
6-
To use LINQ with SolrNet you need to have `ISolrOperations<TEntity>` or even `ISolrBasicReadOnlyOperations<TEntity>` where `TEntity` is a type with properties marked with `SolrField` attribute. For instance
6+
To use LINQ with SolrNet you need to have `ISolrOperations<TEntity>` or even `ISolrBasicReadOnlyOperations<TEntity>`. By default `TEntity` should be a type with properties marked with `SolrField` attribute, however it is not mandatory if you going to set another mapping manager when initializing a query. For instance
77
```
88
public class Product
99
{
@@ -40,7 +40,7 @@ It is possible to combine linq and regular SolrNet QueryOptions and main query.
4040
IQueryable<Product> solrLinq = solr.AsQueryable(setup =>
4141
{
4242
// Set q parameter. By default *:* will be used.
43-
// LINQ Where method append fq (Filter Query) to query options and not affect main query
43+
// LINQ Where method append fq (Filter Query) to query options and not affect main query
4444
options.MainQuery = new SolrQuery("some query");
4545
4646
// Configure SolrNet QueryOptions.
@@ -53,6 +53,9 @@ IQueryable<Product> solrLinq = solr.AsQueryable(setup =>
5353
5454
// override default serializer if needed
5555
options.SolrFieldSerializer = new DefaultFieldSerializer();
56+
57+
// override default mapping manager if needed
58+
options.MappingManager = new AttributesMappingManager();
5659
});
5760
```
5861

SolrNet.IntegrationOData/Controllers/ValuesController.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.AspNetCore.Mvc;
88
using SolrNet.Impl.FieldSerializers;
99
using SolrNet.Linq;
10+
using SolrNet.Mapping;
1011

1112
namespace SolrNet.IntegrationOData.Controllers
1213
{
@@ -52,6 +53,9 @@ public ActionResult<string> Get(int id, ODataQueryOptions odata)
5253

5354
// override default serializer if needed
5455
options.SolrFieldSerializer = new DefaultFieldSerializer();
56+
57+
// override default mapping manager if needed
58+
options.MappingManager = new AttributesMappingManager();
5559
});
5660

5761
return this.Ok(query.OData().ApplyQueryOptionsWithoutSelectExpand(odata).ToSolrQueryResults());

SolrNet.Linq/Expressions/Context/MemberContext.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44
using SolrNet.Impl;
55
using SolrNet.Impl.FieldParsers;
66
using SolrNet.Impl.FieldSerializers;
7+
using SolrNet.Mapping;
78

89
namespace SolrNet.Linq.Expressions.Context
910
{
1011
public abstract class MemberContext
1112
{
1213
private static readonly DefaultFieldSerializer DefaultFieldSerializer = new DefaultFieldSerializer();
14+
private static IReadOnlyMappingManager DefaultMappingManager { get; } = new AttributesMappingManager();
15+
1316
private ISolrFieldSerializer _fieldSerializer;
17+
private IReadOnlyMappingManager _mappingManager;
1418
public abstract bool HasMemberAccess(Expression expression);
1519

1620
public abstract string GetSolrMemberProduct(Expression expression, bool disableFunctions = false);
@@ -42,5 +46,11 @@ public ISolrFieldSerializer FieldSerializer
4246
get => _fieldSerializer ?? DefaultFieldSerializer;
4347
set => _fieldSerializer = value;
4448
}
49+
50+
public IReadOnlyMappingManager MappingManager
51+
{
52+
get => _mappingManager ?? DefaultMappingManager;
53+
set => _mappingManager = value;
54+
}
4555
}
4656
}

SolrNet.Linq/Expressions/MemberExpressionExtensions.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,20 @@ public static class MemberExpressionExtensions
3030

3131
private static readonly ConcurrentDictionary<MemberInfo, string> MemberNames = new ConcurrentDictionary<MemberInfo, string>();
3232

33-
public static string GetMemberSolrName(this MemberInfo info)
33+
private static string GetMemberSolrName(this MemberInfo info, IReadOnlyMappingManager mappingManager)
3434
{
3535
return MemberNames.GetOrAdd(info, m =>
3636
{
37-
SolrFieldAttribute att = m.GetCustomAttributes().OfType<SolrFieldAttribute>().FirstOrDefault();
37+
var att = mappingManager.GetFields(info.DeclaringType);
3838

39-
if (att == null)
39+
SolrFieldModel value = att.Values.FirstOrDefault(f => f.Property == info as PropertyInfo);
40+
if (value != null)
4041
{
41-
throw new InvalidOperationException($"Unable to get solr name for {m.DeclaringType}.{m.Name}");
42+
return value.FieldName;
4243
}
4344

44-
return att.FieldName;
45+
throw new InvalidOperationException(
46+
$"Unable to get solr name for {m.DeclaringType}.{m.Name}. Mapping manager has mappings only for {string.Join(", ", att.Values.Select(f => f.Property.Name))}");
4547
});
4648
}
4749

@@ -57,7 +59,7 @@ internal static string GetSolrMemberProduct(this Expression exp, MemberContext c
5759

5860
if (context.IsAccessToMember(me))
5961
{
60-
return memberInfo.GetMemberSolrName();
62+
return memberInfo.GetMemberSolrName(context.MappingManager);
6163
}
6264

6365
if (me.Member.DeclaringType != null &&

SolrNet.Linq/SolrNet.Linq.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
1414
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
1515
<Version>1.1.0</Version>
16-
<PackageReleaseNotes>ability to customize field serializer</PackageReleaseNotes>
16+
<PackageReleaseNotes>ability to customize field serializer and mapping manager</PackageReleaseNotes>
1717
</PropertyGroup>
1818

1919
<ItemGroup>

SolrNet.Linq/SolrNetLinqOptions.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using SolrNet.Commands.Parameters;
33
using SolrNet.Impl;
4+
using SolrNet.Impl.FieldSerializers;
5+
using SolrNet.Mapping;
46

57
namespace SolrNet.Linq
68
{
@@ -9,10 +11,24 @@ namespace SolrNet.Linq
911
/// </summary>
1012
public class SolrNetLinqOptions
1113
{
14+
/// <summary>
15+
/// Set main query (q SOLR parameter). By default *:* will be used. LINQ Where method append fq (Filter Query) to query options and not affect main query.
16+
/// </summary>
1217
public ISolrQuery MainQuery { get; set; } = null;
1318

19+
/// <summary>
20+
/// Action to perform additional setup of <see cref="QueryOptions"/> SolrNet QueryOptions. Useful to set options not supported by LINQ. Will be applied after translating LINQ expression.
21+
/// </summary>
1422
public Action<QueryOptions> SetupQueryOptions { get; set; } = null;
1523

24+
/// <summary>
25+
/// Set <see cref="ISolrFieldSerializer"/> field serializer. If not set <see cref="DefaultFieldSerializer"/> default SolrNet field serializer will be used.
26+
/// </summary>
1627
public ISolrFieldSerializer SolrFieldSerializer { get; set; } = null;
28+
29+
/// <summary>
30+
/// Set <see cref="IReadOnlyMappingManager"/> field mapping manager. If not set <see cref="AttributesMappingManager"/> attributes mapping manager will be used.
31+
/// </summary>
32+
public IReadOnlyMappingManager MappingManager { get; set; } = null;
1733
}
1834
}

SolrNet.Linq/SolrQueryProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public Task<SolrQueryResults<TEntity>> ExecuteAsync(Expression expression)
5858
SolrQueryTranslator<TEntity> translator = new SolrQueryTranslator<TEntity>(this.Options);
5959
var result = translator.Translate(this, expression);
6060
this.Options.SetupQueryOptions?.Invoke(result.Item2);
61+
6162
return Operations.QueryAsync(this.Options.MainQuery ?? result.Item1, result.Item2);
6263
}
6364

SolrNet.Linq/SolrQueryTranslator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ protected override Expression VisitMethodCall(MethodCallExpression node)
3333
result |= node.TryVisitSkip(this.Options);
3434
MemberContext context = MemberContext.ForType<TEntity>();
3535
context.FieldSerializer = this.SolrNetLinqOptions.SolrFieldSerializer;
36+
context.MappingManager = this.SolrNetLinqOptions.MappingManager;
3637

3738
result |= node.TryVisitSorting(this.Options, context);
3839
result |= node.TryVisitWhere(this.Options, context);

0 commit comments

Comments
 (0)