I have situation where I DO require one-to-one relationship thus the usage of HasOne. Yes I do want to have separate table for Patrons and Members. Following are my classes and their corresponding mapping classes.
public class Member
{
public virtual string ID { get; set; }
public virtual bool IsRegistered { get; set; }
public virtual Patron Patron { get; set; }
public virtual string Reference1 { get; set; }
public virtual string Reference2 { get; set; }
}
public class Patron
{
public virtual string ID { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string Address { get; set; }
public virtual int Telephone1 { get; set; }
public virtual int Telephone2 { get; set; }
public virtual int Age { get; set; }
public virtual string Occupation { get; set; }
public virtual string Gender { get; set; }
public virtual string Room { get; set; }
}
public class PatronMap : ClassMap<Patron>
{
public PatronMap()
{
Id(x => x.ID);
Map(x => x.FirstName);
Map(x => x.LastName);
Map(x => x.Gender);
Map(x => x.Age);
Map(x => x.Address);
Map(x => x.Occupation);
Map(x => x.Telephone1);
Map(x => x.Telephone2);
Map(x => x.Room);
Table("Patrons");
}
}
public class MemberMap : ClassMap<Member>
{
public MemberMap()
{
Id(x => x.ID);
HasOne(x => x.Patron).PropertyRef(x => x.ID).Constrained();
Map(x => x.Reference1);
Map(x => x.Reference2);
Map(x => x.IsRegistered);
Table("Members");
}
}
I also have a little test, as below, to see if the things are mapped correctly or not.
[TestMethod]
public void MemberMap_Create_Success()
{
new PersistenceSpecification<Member>( Database.Session, new CustomEqualityComparer() )
.CheckProperty(x => x.ID, "1")
//I'm not quite sure about the following mapping check. How do I do HasOne check here? :-(
.CheckReference(x => x.Patron, new Patron()
{
ID = "2",
FirstName = "Foo",
LastName = "Bar",
Gender = "M",
Age = 59,
Address = "City, Coutnry",
Telephone1 = 0123456789,
Telephone2 = 0987654321,
Occupation = "Learning Fluent nHibernate",
Room = "Somewhere"
})
.CheckProperty(x => x.Reference1, "Ref1")
.CheckProperty(x => x.Reference2, "Ref2")
.CheckProperty(x => x.IsRegistered, true)
.VerifyTheMappings();
}
I'm not sure how to test HasOne mapping property in this test. Any help is appreciated. Thanks in advance.
Following is what I did to implement HasOne mapping and unit test. Maps are as followed:
public class PatronMap : ClassMap<Patron>
{
public PatronMap()
{
Id(x => x.ID);
Map(x => x.FirstName);
Map(x => x.LastName);
Map(x => x.Gender);
Map(x => x.Age);
Map(x => x.Address);
Map(x => x.Occupation);
Map(x => x.Telephone1);
Map(x => x.Telephone2);
Map(x => x.AshramRoom);
HasOne(x => x.Member).ForeignKey();
Table("Patrons");
}
}
public class MemberMap : ClassMap<Member>
{
public MemberMap()
{
Id(x => x.ID);
Map(x => x.IsRegistered);
Map(x => x.Reference1);
Map(x => x.Reference2);
References(x => x.Patron)
.Column("PatronID")
.Unique()
.UniqueKey("IDX_UniquePatronID");
Table("Members");
}
}
Unit test is as thus:
public void MemberMap_Create_Success()
{
new PersistenceSpecification<Member>( Database.Session, new CustomEqualityComparer() )
.CheckProperty(x => x.ID, "1")
.CheckReference(x => x.Patron, new Patron()
{
ID = "2",
FirstName = "Abc",
LastName = "Xyz",
Gender = "M",
Age = 99,
Address = "Address",
Telephone1 = 0000000001,
Telephone2 = 1000000000,
Occupation = "Occupation",
AshramRoom = "Room"
})
.CheckProperty(x => x.Reference1, "Ref1")
.CheckProperty(x => x.Reference2, "Ref2")
.CheckProperty(x => x.IsRegistered, true)
.VerifyTheMappings();
}
Hope this helps someone. :-)
I know it's been a while but if it helps.
You can use:
var patrol = new Patron()
{
ID = "2",
FirstName = "Foo",
LastName = "Bar",
Gender = "M",
Age = 59,
Address = "City, Coutnry",
Telephone1 = 0123456789,
Telephone2 = 0987654321,
Occupation = "Learning Fluent nHibernate",
Room = "Somewhere"
};
...
.CheckReference(x => x.Patron, patrol)
.CheckProperty(x => x.Reference1, patrol)
.CheckProperty(x => x.Reference2, patrol)
See: https://github.com/jagregory/fluent-nhibernate/wiki/Persistence-specification-testing
Related
I have sealed a class with no constructor which is I am referred using SDK to my project. I want to create fixture data for the class to write test but AutoFixture is giving an expectation like below.
AutoFixture was unable to create an instance from SealedTypeclass, most likely because it has no public constructor, is an abstract or non-public type.
Please find the below code example for which I am trying to create a fixture.
public sealed class TokenCacheItem
{
public string Authority { get; }
public string ClientId { get; }
public DateTimeOffset ExpiresOn { get; }
public string FamilyName { get; }
public string GivenName { get; }
public string IdentityProvider { get; }
public string TenantId { get; }
}
With the above-sealed class i am referring through SDK and I am trying to create fixture data. I am getting the below error message.
Message:
AutoFixture.ObjectCreationExceptionWithPath : AutoFixture was unable to create an instance from ***, most likely because it has no public constructor, is an abstract or non-public type.
Any generic solution?
Given that it's sealed and reporting that it doesn't have a public constructor, you're going to have to provide a way to create an instance and it's probably going to be a reflection based solution. The read only properties add another complexity for AutoFixture as well.
Without seeing the constructor, or whether there are any backing fields for the read only properties I'm going to make some assumptions with the following working example.
Create something that can create a TokenCacheItem and set its properties:
public class MutableTokenCacheItem
{
private TokenCacheItem _tokenCacheItem;
public string Authority { get => _tokenCacheItem.Authority; set => SetPropertyValue(x => x.Authority, value); }
public string ClientId { get => _tokenCacheItem.ClientId; set => SetPropertyValue(x => x.ClientId, value); }
public DateTimeOffset ExpiresOn { get => _tokenCacheItem.ExpiresOn; set => SetPropertyValue(x => x.ExpiresOn, value); }
public string FamilyName { get => _tokenCacheItem.FamilyName; set => SetPropertyValue(x => x.FamilyName, value); }
public string GivenName { get => _tokenCacheItem.GivenName; set => SetPropertyValue(x => x.GivenName, value); }
public string IdentityProvider { get => _tokenCacheItem.IdentityProvider; set => SetPropertyValue(x => x.IdentityProvider, value); }
public string TenantId { get => _tokenCacheItem.TenantId; set => SetPropertyValue(x => x.TenantId, value); }
public MutableTokenCacheItem()
{
var ctor = typeof(TokenCacheItem).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).Single();
_tokenCacheItem = (TokenCacheItem)ctor.Invoke(null);
}
private void SetPropertyValue<P>(Expression<Func<TokenCacheItem, P>> expression, object value)
{
var body = expression.Body as MemberExpression;
var backingField = typeof(TokenCacheItem).GetRuntimeFields().Where(a => Regex.IsMatch(a.Name, $"\\A<{body.Member.Name}>k__BackingField\\Z")).Single();
backingField.SetValue(_tokenCacheItem, value);
}
public TokenCacheItem AsImmutableTokenCacheItem()
{
return _tokenCacheItem;
}
}
Create a specimen builder to bolt it into AutoFixture nicely:
public class TokenCacheItemSpecimenBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var t = request as Type;
if (typeof(TokenCacheItem).Equals(t))
{
var mutableTokenCacheItem = context.Create<MutableTokenCacheItem>();
return mutableTokenCacheItem.AsImmutableTokenCacheItem();
}
return new NoSpecimen();
}
}
Add the customization and off you go:
var fixture = new Fixture();
fixture.Customizations.Add(new TokenCacheItemSpecimenBuilder());
fixture.Create<TokenCacheItem>();
Working LINQPad example:
void Main()
{
var fixture = new Fixture();
fixture.Customizations.Add(new TokenCacheItemSpecimenBuilder());
Console.Write(fixture.Create<TokenCacheItem>());
}
public class TokenCacheItemSpecimenBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var t = request as Type;
if (typeof(TokenCacheItem).Equals(t))
{
var mutableTokenCacheItem = context.Create<MutableTokenCacheItem>();
return mutableTokenCacheItem.AsImmutableTokenCacheItem();
}
return new NoSpecimen();
}
}
public class MutableTokenCacheItem
{
private TokenCacheItem _tokenCacheItem;
public string Authority { get => _tokenCacheItem.Authority; set => SetPropertyValue(x => x.Authority, value); }
public string ClientId { get => _tokenCacheItem.ClientId; set => SetPropertyValue(x => x.ClientId, value); }
public DateTimeOffset ExpiresOn { get => _tokenCacheItem.ExpiresOn; set => SetPropertyValue(x => x.ExpiresOn, value); }
public string FamilyName { get => _tokenCacheItem.FamilyName; set => SetPropertyValue(x => x.FamilyName, value); }
public string GivenName { get => _tokenCacheItem.GivenName; set => SetPropertyValue(x => x.GivenName, value); }
public string IdentityProvider { get => _tokenCacheItem.IdentityProvider; set => SetPropertyValue(x => x.IdentityProvider, value); }
public string TenantId { get => _tokenCacheItem.TenantId; set => SetPropertyValue(x => x.TenantId, value); }
public MutableTokenCacheItem()
{
var ctor = typeof(TokenCacheItem).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).Single();
_tokenCacheItem = (TokenCacheItem)ctor.Invoke(null);
}
private void SetPropertyValue<P>(Expression<Func<TokenCacheItem, P>> expression, object value)
{
var body = expression.Body as MemberExpression;
var backingField = typeof(TokenCacheItem).GetRuntimeFields().Where(a => Regex.IsMatch(a.Name, $"\\A<{body.Member.Name}>k__BackingField\\Z")).Single();
backingField.SetValue(_tokenCacheItem, value);
}
public TokenCacheItem AsImmutableTokenCacheItem()
{
return _tokenCacheItem;
}
}
public sealed class TokenCacheItem
{
public string Authority { get; }
public string ClientId { get; }
public DateTimeOffset ExpiresOn { get; }
public string FamilyName { get; }
public string GivenName { get; }
public string IdentityProvider { get; }
public string TenantId { get; }
private TokenCacheItem() { }
}
Result:
YMMV depending on the actual TokenCacheItem implementation though it's probably not far off.
The below classes in Domain Emtity:
public class SecondaryCustomerProfile
{
public int Id { get; set; }
public List<SecondaryCustomerProfileProductType> ProductTypes { get; set; }
}
public class SecondaryCustomerProfileProductType
{
public int IdField { get; set; }
public int SecondaryCustomerProfileIdField { get; set; }
public string TypeField { get; set; }
}
//The following class in WCF Service
public class SecondaryCustomerProfile
{
public int Id { get; set; }
public SecondaryCustomerProfileProductType[] ProductTypes { get; set; }
}
public class SecondaryCustomerProfileProductType
{
public int Id{ get; set; }
public int SecondaryCustomerProfileIdField { get; set; }
public string Type{ get; set; }
}
Now when I am trying to map as following...
Mapper.CreateMap<Core.DomainEntities.SecondaryCustomerProfile, Core.CustomerService.SecondaryCustomerProfile>()
.ForMember(d => d.Id, m => m.MapFrom(s => s.Id))
.ForMember(d => d.ProductTypes, m => m.MapFrom(s => s.ProductTypes));
Mapper.CreateMap<Core.DomainEntities.SecondaryCustomerProfileProductType, Core.CustomerService.SecondaryCustomerProfileProductType>()
.ForMember(d => d.Id, m => m.MapFrom(s => s.IdField))
.ForMember(d => d.SecondaryCustomerProfileId, m => m.MapFrom(s => s.SecondaryCustomerProfileIdField))
.ForMember(d => d.Type, m => m.MapFrom(s => s.TypeField));
Mapper.Map<DomainEntities.SecondaryCustomerProfile, CustomerService.SecondaryCustomerProfile>(profile);
I am getting error:
AutoMapper.AutoMapperMappingException was unhandled by user code
HResult=-2146233088
Message=Missing type map configuration or unsupported mapping.
Mapping types:
SecondaryCustomerProfile -> SecondaryCustomerProfile
DomainEntities.SecondaryCustomerProfile -> CustomerService.SecondaryCustomerProfile
Destination path:
SecondaryCustomerProfile
Source value:
DomainEntities.SecondaryCustomerProfile
Source=AutoMapper
StackTrace:
at Services\Customer\CustomerCoreService.cs:line 75
at CustomerController.Save(List`1 secondaryCustomerProfileModels) in C:\Test\CustomerController.cs:line 99
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
InnerException:
.
I am trying to populate a dropdownlistfor in my view and I don't know the correct lambda expression for it to work. See code below:
#model Website.Models.modelTeamSelect
<h2>MatchSelect.cshtml</h2>
#using (Ajax.BeginForm("_PartialTeams",
new
{
model = this.Model
},
new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "divMatchScheduler",
InsertionMode = InsertionMode.Replace
}))
{
<div id="divMatchScheduler">
#Html.LabelFor(m => m.modelMatch.HomeTeam)
#Html.DropDownListFor(m => m.modelMatch.HomeTeam, new SelectList
{
Items = Model.teams.Select(t => t.TeamName)
})
#Html.LabelFor(m => m.modelMatch.AwayTeam)
#Html.LabelFor(m => m.modelMatch.MatchDate)
#Html.TextBoxFor(m => m.modelMatch.MatchDate)
</div>
<input type="submit" value="Add Match" name="btnSubmit" />
}
This syntax is wrong
#Html.DropDownListFor(m => m.modelMatch.HomeTeam, new SelectList
{
Items = Model.teams.Select(t => t.TeamName)
})
My model being used by the view and the collection it contains
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Website.Models
{
public class modelMatch
{
public Guid MatchID { get; set; }
public Guid AwayTeamID { get; set; }
public string AwayTeam { get; set; }
public Guid HomeTeamID { get; set; }
public string HomeTeam { get; set; }
public DateTime MatchDate { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Website.Models
{
public class modelTeamSelect
{
public modelTeamSelect()
{
teams = new List<modelTeam>();
team = new modelTeam();
modelMatch = new Models.modelMatch();
modelMatches = new List<modelMatch>();
}
public List<modelTeam> teams { get; set; }
public modelTeam team { get; set; }
public modelMatch modelMatch { get; set; }
public List<modelMatch> modelMatches { get; set; }
public string message { get; set; }
}
}
Summary
How do I populate dropdownlistfor using a list collection that is in my model?
For most cases you'll want to use this overload of SelectList to populate your dropdowns.
#Html.DropDownListFor(m => m.modelMatch.HomeTeam, new SelectList(Model.teams, "dataValueField", "dataTextField"))
dataValueField and dataTextField are the properties from your modelTeam model that will be used as value and text for the dropdown.
#{
<br />
ViewBag.TeamList = Model.teams.Select(t => t.TeamName);
<br />
}
<br />
#Html.DropDownListFor(m => m.modelMatch.HomeTeam, ViewBag.TeamList as SelectList)
You also can create HtmlHelperExtensions class to bind dropdowns.
public static IEnumerable<SelectListItem> ObtenerPais(this HtmlHelper helper)
{
var cnx = new db();
var resultado = cnx.PAIS.ToList()
.Select(e => new SelectListItem
{
Text = e.NOMBRE,
Value = Convert.ToString(e.ID_PAIS)
}).ToList();
//if (Default)
resultado.Insert(0, new SelectListItem
{
Text = "-- Seleccionar --",
Value = ""
});
return resultado;
}
And for use it:
#Html.DropDownListFor(model => model.ID_ENTIDAD, Html.ObtenerPais(Default: true))
Hope this helps
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm having some trouble with date formats in indexes. They're
serializing to something indeserializable. Our entities have this
shape:
[Serializable]
public class Publication
{
public Guid? Id { get; set; }
public PublicationRendering Rendering { get; protected internal set; }
public DateRange SuggestedActiveRange { get; protected set; }
public DateRange ActualActiveRange { get; protected internal set; }
...
}
public class DateRange
{
public DateTime StartDate { get; private set; }
public DateTime? EndDate { get; set; }
...
}
The document is serialized properly:
publications/806059ce-fd7a-4655-8e0e-9fff00f5ebd3
{
...
"SuggestedActiveRange": {
"StartDate": "2011-11-22T00:00:00.0000000Z",
"EndDate": "2012-01-22T00:00:00.0000000Z",
"TimeSpan": "61.00:00:00"
},
"ActualActiveRange": {
"StartDate": "2011-11-22T00:00:00.0000000Z",
"EndDate": "2012-01-22T00:00:00.0000000Z",
"TimeSpan": "61.00:00:00"
},
...
}
And I'm defining my index as such (it's a multi-reduce):
public class PublishedPolicyIndex :
AbstractMultiMapIndexCreationTask<PublishedPolicyIndex.ReduceResult>
{
public PublishedPolicyIndex() {
AddMap<Publication>(publications => publications.Select(publication => new {
ArtifactId = "artifacts/" + publication.Rendering.ArtifactId,
ActiveStartDate = publication.ActualActiveRange.StartDate,
ActiveEndDate = publication.ActualActiveRange.EndDate,
ViewingPrincipals = (string[]) null,
...
}));
AddMap<Artifact>(artifacts => artifacts.Select(artifact => new {
ArtifactId = artifact.Id,
ActiveStartDate = (string) null,
ActiveEndDate = (string) null,
artifact.ViewingPrincipals,
...
}));
Reduce = results => results.GroupBy(result => result.ArtifactId).Select(g => new {
ArtifactId = g.Key,
ActiveStartDate = g.Select(x => x.ActiveStartDate).SingleOrDefault(x => x != null),
ActiveEndDate = g.Select(x => x.ActiveEndDate).SingleOrDefault(x => x != null),
ViewingPrincipals = g.Select(x => x.ViewingPrincipals).SingleOrDefault(x => x != null),
...
});
Analyzers = new Dictionary<Expression<Func<ReduceResult, object>>, string> {
{rr => rr.ActiveStartDate, "Lucene.Net.Analysis.Standard.StandardAnalyzer"},
{rr => rr.ActiveEndDate, "Lucene.Net.Analysis.Standard.StandardAnalyzer"},
...
};
Stores.Add(x => x.ActiveStartDate, FieldStorage.Yes);
Stores.Add(x => x.ActiveEndDate, FieldStorage.Yes);
}
public class ReduceResult : IReduceResults
{
public string ArtifactId { get; set; }
public string ActiveStartDate { get; set; }
public string ActiveEndDate { get; set; }
public string[] ViewingPrincipals { get; set; }
...
}
}
But when I look in my index I have this data:
{
"ArtifactId": "artifacts/533b8cba-8b8f-4c23-b89a-9fff00f5ebd3",
"ActiveStartDate": "20111122000000000",
"ActiveEndDate": "20120322000000000",
"ViewingPrincipals": [
"b0202923-eb07-493d-a0b5-9fff00f5ebd3"
],
...
}
It's almost as if it were hashing these dates. Maybe I didn't setup
my field store correctly? If I explicitly call .ToString("u"), it
will store the dates in a format that can be deserialized, but not
quite equal to the format I want, plus that's too messy.
In RavenDB I understand when you require to count properties matching a certain criteria, it can be achieved
by creating facets against those property names you wish to group,
and then creating an index over the above properties and the properties required in the where clause.
and finally issuing a query by using the above index. and materializing the query using the ToFacets extension.
But what happens when your where clause happens to contain a predicate against a property that is a collection of values on the document? Because if I add the nested property from the collection to the index against the parent document, my facet counts on properties on the parent document will not be accurate?
for e.g.
public class Camera {
string Make { get;set; }
string Model { get;set; }
double Price { get;set; }
IEnumerable<string> Showrooms { get;set; }
}
My query would look like
(from camera in session.Query<Camera, Camera_Facets>()
where camera.Price < 100 && camera.ShowRooms.Any(s => s.In("VIC", "ACT", "QLD"))
select new {
camera.Make,
camera.Model,
camera.Price}
).ToFacets("facets/CameraFacets");
Update:
Here is the failing test
[TestFixture]
public class FacetedSearchWhenQueryingNestedCollections
{
public class Car
{
public Car()
{
Locations = new List<string>();
}
public string Id { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public double Price { get; set; }
public IEnumerable<string> Locations { get; set; }
}
public class Car_Facets : AbstractIndexCreationTask<Car>
{
public Car_Facets()
{
Map = cars => from car in cars
select new {car.Make, car.Model, car.Price};
}
}
private static IDocumentSession OpenSession
{
get { return new EmbeddableDocumentStore {RunInMemory = true}.Initialize().OpenSession(); }
}
[Test]
public void CanGetFacetsWhenQueryingNesetedCollectionValues()
{
var cars = Builder<Car>.CreateListOfSize(50)
.Section(0, 10)
.With(x => x.Model = "Camry")
.With(x => x.Make = "Toyota")
.With(x => x.Price = 2000)
.With(x => x.Locations = new[] {"VIC", "ACT"})
.Section(11, 20)
.With(x => x.Model = "Corolla")
.With(x => x.Make = "Toyota")
.With(x => x.Price = 1000)
.With(x => x.Locations = new[] { "NSW", "ACT" })
.Section(21, 30)
.With(x => x.Model = "Rx8")
.With(x => x.Make = "Mazda")
.With(x => x.Price = 5000)
.With(x => x.Locations = new[] { "ACT", "SA", "TAS" })
.Section(31, 49)
.With(x => x.Model = "Civic")
.With(x => x.Make = "Honda")
.With(x => x.Price = 1500)
.With(x => x.Locations = new[] { "QLD", "SA", "TAS" })
.Build();
IDictionary<string, IEnumerable<FacetValue>> facets;
using(var s = OpenSession)
{
s.Store(new FacetSetup { Id = "facets/CarFacets", Facets = new List<Facet> { new Facet { Name = "Model" }, new Facet { Name = "Make" }, new Facet { Name = "Price" } } });
s.SaveChanges();
IndexCreation.CreateIndexes(typeof(Car_Facets).Assembly, s.Advanced.DocumentStore);
foreach (var car in cars)
s.Store(car);
s.SaveChanges();
s.Query<Car, Car_Facets>().Customize(x => x.WaitForNonStaleResults()).ToList();
facets = s.Query<Car, Car_Facets>()
.Where(x => x.Price < 3000)
.Where(x => x.Locations.Any(l => l.In("QLD", "VIC")))
.ToFacets("facets/CarFacets");
}
Assert.IsNotNull(facets);
Assert.IsTrue(facets.All(f => f.Value.Count() > 0));
Assert.IsTrue(facets.All(f => f.Value.All(x => x.Count > 0)));
}
[TearDown]
public void ClearData()
{
using(var s = OpenSession)
{
foreach (var car in s.Query<Car>().ToList())
s.Delete(car);
s.SaveChanges();
}
}
}
But if I change my query to be. (not querying the nested collection any more)
facets = s.Query<Car, Car_Facets>()
.Where(x => x.Price < 3000)
.ToFacets("facets/CarFacets");
Now I get 3 Enumerations in the dictionary, all with values.
if I change my index to be
public class Car_Facets : AbstractIndexCreationTask<Car>
{
public Car_Facets()
{
Map = cars => from car in cars
from location in car.Locations
select new {car.Make, car.Model, car.Price, Location = location};
}
}
Create a class for the projection
public class CarOnLocation
{
public string Make { get; set; }
public string Model { get; set; }
public double Price { get; set; }
public string Location { get; set; }
}
And then query as
facets = s.Query<Car, Car_Facets>().AsProjection<CarOnLocation>()
.Where(x => x.Price < 3000)
.Where(x => x.Location.In("QLD", "VIC"))
.ToFacets("facets/CarFacets");
it works.