-
Type:
Improvement
-
Resolution: Done
-
Priority:
Major - P3
-
None
-
Affects Version/s: 1.8.1
-
Component/s: None
-
None
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Currently, it is impossible to have a readonly public member that is backed by a private member take part in LINQ queries. The below example illustrates as much:
namespace MongoBug
{
using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using NUnit.Framework;
/// <summary>
/// Test fixture showing issue with using LINQ queries against a backing field
/// </summary>
[TestFixture]
public class LinqBugTestFixture
{
/// <summary>
/// The connection string
/// </summary>
private const string ConnectionString = "mongodb://localhost:27017/mapping_private_field";
/// <summary>
/// Gets or sets the database.
/// </summary>
/// <value>
/// The database.
/// </value>
private MongoDatabase Database { get; set; }
/// <summary>
/// Sets up the mapping for mongo.
/// </summary>
[TestFixtureSetUp]
public void MapMongo()
{
var url = new MongoUrl(ConnectionString);
var client = new MongoClient(url);
this.Database = client.GetServer().GetDatabase(url.DatabaseName);
this.Database.DropCollection("sampleModels");
BsonClassMap.RegisterClassMap<SampleModel>(cm =>
{
cm.MapIdProperty(c => c.Id);
cm.MapField("children").SetElementName("Children");
});
}
/// <summary>
/// Tests revealing the missing mapping use case.
/// </summary>
[Test]
public void TestShowMissingUseCase()
{
var model = new SampleModel();
model.AddChild(new ChildrenModel { Name = "One" });
model.AddChild(new ChildrenModel { Name = "Two" });
model.AddChild(new ChildrenModel { Name = "Three" });
var collection = this.Database.GetCollection<SampleModel>("sampleModels");
collection.Save(model);
var fromMongo = (from sample in collection.AsQueryable()
where sample.Children.Any(s => s.Name == "Two")
select sample).FirstOrDefault();
Assert.AreEqual(model.Id, fromMongo.Id);
}
#region Model Class
/// <summary>
/// Sample Model that shows bug accessing private backing field through LINQ queries
/// </summary>
public class SampleModel
{
/// <summary>
/// The backing field
/// </summary>
private IList<ChildrenModel> children;
/// <summary>
/// Initializes a new instance of the <see cref="SampleModel"/> class.
/// </summary>
public SampleModel()
{
this.children = new List<ChildrenModel>();
}
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>
/// The id.
/// </value>
public ObjectId Id { get; set; }
/// <summary>
/// Gets the strings.
/// </summary>
/// <value>
/// The strings.
/// </value>
public IEnumerable<ChildrenModel> Children
{
get { return this.children; }
}
/// <summary>
/// Adds a child.
/// </summary>
/// <param name="toAdd">The child to add.</param>
public void AddChild(ChildrenModel toAdd)
{
this.children.Add(toAdd);
}
}
/// <summary>
/// The child document
/// </summary>
public class ChildrenModel
{
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>
/// The name.
/// </value>
public string Name { get; set; }
}
#endregion
}
}