Mapping is broken?
Hi! Sorry for very bad english. Strange situation. On all project all OK, but some code work wrong/ After second call mapping don't work. For sample come classes:
[Serializable]
public class ItemGroup {
public int Id { get; set; }
public string Name { get; set; }
}
[Serializable]
public class ItemType {
public int Id { get; set; }
public string Name { get; set; }
public ItemGroup ItemGroup { get; set; } <--- = null on second call
public ItemType() {
ItemGroup = new ItemGroup();
}
}
[Serializable]
public class Item {
public int Id { get; set; }
public string Name { get; set; }
public ItemType ItemType { get; set; } // <--- = null on second call
// …
[MapIgnore] public string ItemTypeName { get { return ItemType.Name; } }
[MapIgnore] public string ItemGroupName { get { return ItemType.ItemGroup.Name; } }
// …
public Item() {
ItemType = new ItemType();
}
}
In ItemRepository:
public class ItemRepository {
private const string GetItemsQuery = @"
SELECT i.Id AS [Id],
i.Name AS [Name],
t.Id AS [ItemType.Id],
t.Name AS [ItemType.Name],
g.Id AS [ItemType.ItemGroup.Id],
g.Name AS [ItemType.ItemGroup.Name]
FROM Items i
JOIN ItemTypes t
JOIN ItemGroups g
ON t.GroupId = g.Id
ON i.TypeId = t.Id
WHERE g.Id = @groupId
AND t.Id = @typeId";
public List<Item> GetItems(int groupId, int typeId) { // <- on second call this method marked fields is null
using (var db = new DbManager()) {
return db.SetCommand(GetItemsQuery,
db.Parameter("@groupId", groupId),
db.Parameter("@typeId", typeId))
.ExecuteList<Item>();
}
}
}
On code
private void ShowData(int groupId, int typeId) {
var items = itemsRepository.GetItems(groupId, typeid);
itemsBindingSource.DataSource = new BindingListImpl(Filter(items), typeof(Item));
}
On first call ShowData() all fields have good data (Item.ItemType != null, Item.ItemType.ItemGroup != null), but after second and next calls Item.ItemType=null and ItemType.ItemGroup =null, but in database all OK. Second and next calls db.ExecuteList<Item>() return invalid object with null properies. Query in database is correct and return correct data, Behaviour like not called default constructor (without parameters) on ItemType and ItemGroup or broken mapping. In other parts of program all correct, but two or three methods is broken.
BLToolkit last version. .NetFramework 4.0.
@AlexLook sorry for really late responce, but projet is suspended.
Speaking about your case it is really strange, if no factories are used objects would be initialized with default constructors. During the mapping only primitive properties are set, so null value could not be set for the ItemType.ItemGroup property, so i'm confused little bit.
I can advice you trying to specify more detailed mapping configuration with MapFieldAttibute:
[Serializable]
public class ItemGroup {
public int Id { get; set; }
public string Name { get; set; }
}
[Serializable]
public class ItemType {
public int Id { get; set; }
public string Name { get; set; }
[MapField(Format="ItemGroup.{0}"]
public ItemGroup ItemGroup { get; set; } //<--- = null on second call
public ItemType() {
ItemGroup = new ItemGroup();
}
}
[Serializable]
public class Item {
public int Id { get; set; }
public string Name { get; set; }
[MapField(Format="ItemType.{0}"]
public ItemType ItemType { get; set; } // <--- = null on second call
// …
[MapIgnore] public string ItemTypeName { get { return ItemType.Name; } }
[MapIgnore] public string ItemGroupName { get { return ItemType.ItemGroup.Name; } }
// …
public Item() {
ItemType = new ItemType();
}
}
More detailed at: https://github.com/igor-tkachev/bltoolkit/wiki/Mapping.MapFieldAttribute