Browse Source

Fixed CSHARP-81. The IdPropertyMap for a class map should come from the highest class possible in the inheritance hierarchy.

pull/10/head
rstam 15 years ago
parent
commit
c35dcfeabc
  1. 52
      Bson/DefaultSerializer/BsonClassMap.cs
  2. 1
      BsonUnitTests/BsonUnitTests.csproj
  3. 59
      BsonUnitTests/Jira/CSharp81Tests.cs

52
Bson/DefaultSerializer/BsonClassMap.cs

@ -40,6 +40,7 @@ namespace MongoDB.Bson.DefaultSerializer {
protected string discriminator; protected string discriminator;
protected bool discriminatorIsRequired; protected bool discriminatorIsRequired;
protected bool isAnonymous; protected bool isAnonymous;
protected bool idPropertyMapLoaded; // lazy load idPropertyMap
protected BsonPropertyMap idPropertyMap; protected BsonPropertyMap idPropertyMap;
protected List<BsonPropertyMap> propertyMaps = new List<BsonPropertyMap>(); protected List<BsonPropertyMap> propertyMaps = new List<BsonPropertyMap>();
protected bool ignoreExtraElements = true; protected bool ignoreExtraElements = true;
@ -82,16 +83,8 @@ namespace MongoDB.Bson.DefaultSerializer {
public BsonPropertyMap IdPropertyMap { public BsonPropertyMap IdPropertyMap {
get { get {
if (idPropertyMap != null) {
return idPropertyMap;
} else {
var baseClassMap = BaseClassMap; // call property for lazy loading
if (baseClassMap != null) {
return baseClassMap.IdPropertyMap;
} else {
return null;
}
}
if (!idPropertyMapLoaded) { LoadIdPropertyMap(); }
return idPropertyMap;
} }
} }
@ -377,19 +370,6 @@ namespace MongoDB.Bson.DefaultSerializer {
propertyMaps = new List<BsonPropertyMap>(ordered.Concat(propertyMaps.Where(pm => pm.Order == int.MaxValue))); propertyMaps = new List<BsonPropertyMap>(ordered.Concat(propertyMaps.Where(pm => pm.Order == int.MaxValue)));
} }
// TODO: improve Id detection algorithm (doesn't have to be perfect since BsonIdAttribute can always pinpoint the Id property)
// simple algorithm: first property found that ends in either "Id" or "id" or is of type ObjectId or Guid
if (idPropertyMap == null) {
idPropertyMap = propertyMaps
.Where(pm =>
pm.PropertyName.EndsWith("Id") ||
pm.PropertyName.EndsWith("id") ||
pm.PropertyType == typeof(ObjectId) ||
pm.PropertyType == typeof(Guid)
)
.FirstOrDefault();
}
RegisterDiscriminator(classType, discriminator); RegisterDiscriminator(classType, discriminator);
} }
@ -452,6 +432,32 @@ namespace MongoDB.Bson.DefaultSerializer {
} }
baseClassMapLoaded = true; baseClassMapLoaded = true;
} }
private void LoadIdPropertyMap() {
if (idPropertyMap == null) {
// the IdPropertyMap should be provided by the highest class possible in the inheritance hierarchy
var baseClassMap = BaseClassMap; // call BaseClassMap property for lazy loading
if (baseClassMap != null) {
idPropertyMap = baseClassMap.IdPropertyMap;
}
// if no base class provided an idPropertyMap maybe we have one?
if (idPropertyMap == null) {
// TODO: improve Id detection algorithm (doesn't have to be perfect since BsonIdAttribute can always pinpoint the Id property)
// simple algorithm: first property found that ends in either "Id" or "id" or is of type ObjectId or Guid
idPropertyMap = propertyMaps
.Where(pm =>
pm.PropertyName.EndsWith("Id") ||
pm.PropertyName.EndsWith("id") ||
pm.PropertyType == typeof(ObjectId) ||
pm.PropertyType == typeof(Guid)
)
.FirstOrDefault();
}
}
idPropertyMapLoaded = true;
}
#endregion #endregion
} }

1
BsonUnitTests/BsonUnitTests.csproj

@ -80,6 +80,7 @@
<Compile Include="Jira\CSharp74Tests.cs" /> <Compile Include="Jira\CSharp74Tests.cs" />
<Compile Include="DefaultSerializer\Attributes\BsonAttributeTests.cs" /> <Compile Include="DefaultSerializer\Attributes\BsonAttributeTests.cs" />
<Compile Include="Jira\CSharp78Tests.cs" /> <Compile Include="Jira\CSharp78Tests.cs" />
<Compile Include="Jira\CSharp81Tests.cs" />
<Compile Include="ObjectModel\BsonDocumentTests.cs" /> <Compile Include="ObjectModel\BsonDocumentTests.cs" />
<Compile Include="ObjectModel\BsonElementTests.cs" /> <Compile Include="ObjectModel\BsonElementTests.cs" />
<Compile Include="ObjectModel\BsonEqualsTests.cs" /> <Compile Include="ObjectModel\BsonEqualsTests.cs" />

59
BsonUnitTests/Jira/CSharp81Tests.cs

@ -0,0 +1,59 @@
/* Copyright 2010 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;
using NUnit.Framework;
using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.DefaultSerializer;
using MongoDB.Bson.Serialization;
namespace MongoDB.BsonUnitTests.Jira {
[TestFixture]
public class CSharp81Tests {
private class BaseModel {
[BsonId]
public ObjectId Id { get; set; }
}
private class User : BaseModel {
public ObjectId FriendId { get; set; }
}
[Test]
public void TestIdProperty() {
var u = new User { Id = ObjectId.Empty, FriendId = ObjectId.Empty };
var classMap = BsonClassMap.LookupClassMap(typeof(User));
var idPropertyMap = classMap.IdPropertyMap;
Assert.AreEqual("Id", idPropertyMap.PropertyName);
var serializer = BsonSerializer.LookupSerializer(typeof(User));
var idGenerator = BsonSerializer.LookupIdGenerator(typeof(ObjectId));
serializer.GenerateDocumentId(u);
Assert.IsFalse(idGenerator.IsEmpty(u.Id));
Assert.IsTrue(idGenerator.IsEmpty(u.FriendId));
var json = u.ToJson();
}
}
}
Loading…
Cancel
Save