|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2011-04-13 12:29:45
Posts: 75,
Visits: 544
|
|
HI All
i've read this article for understanding what is the purpose of the multiDB mapper, http://www.capableobjects.com/apps/InstantKB13/KnowledgebaseArticle50007.aspx
so when i'm trying to do somthing, there is errors such as "root obkect not persisted".
I'm try to use source from \source\ folder to recompile the eco.persistence and other mappers .SQlite. but this doesn't help more.
i've read "how to" guide? but this doesn't help too.
what is the questions:
i need to access the data that resides or will reside in the different databses. so i think i can use MultiDB for that purpose.
but how to model such i don't understand yet.
is there any working example of multiple database support, to have see how it works?
if no, i will try to propose one when i get it working.
Alex
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2011-04-13 12:29:45
Posts: 75,
Visits: 544
|
|
i use Eco
5.0.0.4874
steps:
- i've create a simple ECO project.
- default pmp is DB1
- within Mdlr create two classes in default package, with 1..* relationship.
- create default xml mapping file and add filemapping provider.
- setup for persistence mapper file mapping provider
- run.
works!
- add new package and adds another two classes with relationship beetween them
- generate code and change in ecospace selected packages to use new one instead of old one
- add new Pmp called DB2
- generate default mapping and add filemapping provide
- setup for new persistence mapper file with new mapping provider
- in PMP select new PMP as default one.
- run.
works!
- add new MultiDB pm
- add two entries named DB1 with DB1 pmp, and called DB2 with DB2 pmp.
- setup import config = true for both entries
- select both packages in Ecospace
- run.
exception with call stack
System.NullReferenceException: В экземпляре объекта не задана ссылка на объект.
в Eco.Persistence.ORMapping.ColumnTypeFixer.FixAttribute(AttributeDefinition attrDef, IAttribute attr) в e:\dev\Eco5.x\source\Eco\Eco.Persistence\ORMapping\ORMappingTypeFixer.cs:строка 194
в Eco.Persistence.ORMapping.ColumnTypeFixer.Fixit() в e:\dev\Eco5.x\source\Eco\Eco.Persistence\ORMapping\ORMappingTypeFixer.cs:строка 79
в Eco.Persistence.ORMapping.ColumnTypeFixer.FixTypes(ORMappingDefinition mapping, SqlDatabaseConfig config, IEcoTypeSystem model) в e:\dev\Eco5.x\source\Eco\Eco.Persistence\ORMapping\ORMappingTypeFixer.cs:строка 23
в Eco.Persistence.PersistenceMapperMultiDb.GetCompoundMapping(ITypeSystemService typeSystemService, IDatabaseCollection databases, CreateMappingMode mode) в e:\dev\Eco5.x\source\Eco\Eco.Persistence\PersistenceMapperMultiDb.cs:строка 145
в Eco.Persistence.PersistenceMapperMultiDb.GetPersistenceMapper(ITypeSystemService typeSystemService) в e:\dev\Eco5.x\source\Eco\Eco.Persistence\PersistenceMapperMultiDb.cs:строка 180
в Eco.Persistence.PersistenceMapperProvider.GetPersistenceMapper(ITypeSystemService typeSystemService) в e:\dev\Eco5.x\source\Eco\Eco.Persistence\PersistenceMapperProvider.cs:строка 219
в Eco.Persistence.PersistenceMapperSharer.GetPersistenceMapper(ITypeSystemService typeSystemService) в e:\dev\Eco5.x\source\Eco\Eco.Persistence\PersistenceMapperSharer.cs:строка 90
в Eco.Handles.DefaultEcoSpace.Setup() в e:\dev\Eco5.x\source\Eco\Eco.Handles\Handles\DefaultEcoSpace.cs:строка 222
в Eco.Handles.DefaultEcoSpace.set_Active(Boolean value) в e:\dev\Eco5.x\source\Eco\Eco.Handles\Handles\DefaultEcoSpace.cs:строка 174
в EcoMultiDBSample.Program.Main() в D:\Work\EcoMultiDB\EcoMultiDBSample\EcoMultiDBSample\Program.cs:строка 36
Alex
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2011-04-13 12:29:45
Posts: 75,
Visits: 544
|
|
found bug, will post bug report and solution:
PersistenceMapperMultiDB.cs
was the code
private ORMappingDefinition GetCompoundMapping(ITypeSystemService typeSystemService, IDatabaseCollection databases, CreateMappingMode mode)
{
ORMappingDefinition mergedMapping = new ORMappingDefinition();
if (RunTimeMappingProvider != null)
{
MergeMapping(typeSystemService, mergedMapping, RunTimeMappingProvider, null, null, "", mode);
}
foreach (PMapperDef def in PersistenceMappers)
{
if (def.Mapper != null && def.ImportConfig)
{
IORMappingProvider mappingProvider = def.Mapper.RunTimeMappingProvider;
if (mappingProvider == null)
{
DefaultORMappingBuilder implicitMappingProvider = new DefaultORMappingBuilder();
implicitMappingProvider.Database = def.Name;
mappingProvider = implicitMappingProvider;
def.Mapper.RunTimeMappingProvider = mappingProvider;
}
IDatabase db = databases.GetDatabase(def.Name);
MergeMapping(typeSystemService, mergedMapping,
mappingProvider,
(mode == CreateMappingMode.Run) ? db : null,
db.Config,
def.Name,
mode);
}
}
ColumnTypeFixer.FixTypes(mergedMapping, null, typeSystemService.TypeSystem);
mergedMapping.Validate(null, typeSystemService.TypeSystem);
return mergedMapping;
}
when calling this method without second parameters later persistence throws exception by exceptions with reference null because this parameter initialize m_Config, m_MapperDictionary, m_Int32Mapper that actually used to retrive values from PS queries.
m_Config(SQLDatabaseConfig) method public string DeQuoteName(string quotedName) is used to get UnquotedName of column. the UnquotedName used when we reads values from dataset
IField aField = DataSet.FieldByName(ColumnReferences[0].Column.UnquotedName);
so if UnquotedName is empty then Column Index became -1. that throws exception.
to fix that i just replace the code with next one
private ORMappingDefinition GetCompoundMapping(ITypeSystemService typeSystemService, IDatabaseCollection databases, CreateMappingMode mode)
{
ORMappingDefinition mergedMapping = new ORMappingDefinition();
if (RunTimeMappingProvider != null)
{
MergeMapping(typeSystemService, mergedMapping, RunTimeMappingProvider, null, null, "", mode);
}
foreach (PMapperDef def in PersistenceMappers)
{
if (def.Mapper != null && def.ImportConfig)
{
IORMappingProvider mappingProvider = def.Mapper.RunTimeMappingProvider;
if (mappingProvider == null)
{
DefaultORMappingBuilder implicitMappingProvider = new DefaultORMappingBuilder();
implicitMappingProvider.Database = def.Name;
mappingProvider = implicitMappingProvider;
def.Mapper.RunTimeMappingProvider = mappingProvider;
}
IDatabase db = databases.GetDatabase(def.Name);
MergeMapping(typeSystemService, mergedMapping,
mappingProvider,
(mode == CreateMappingMode.Run) ? db : null,
db.Config,
def.Name,
mode);
}
// here changes to be done
var db1 = databases.GetDatabase(def.Name);
ColumnTypeFixer.FixTypes(mergedMapping, db1.Config, typeSystemService.TypeSystem);
// this done to use current db.config to fix column names in merged mapping.
}
// old code
//ColumnTypeFixer.FixTypes(mergedMapping, null, typeSystemService.TypeSystem);
mergedMapping.Validate(null, typeSystemService.TypeSystem);
return mergedMapping;
}
---
may be there is better solution, will find out tomorrow.
Alex
|
|
|
|
|
Forum Guru
      
Group: Forum Members
Last Login: Yesterday @ 20:21:00
Posts: 55,
Visits: 3 211
|
|
It is Johnas's answer - me:
"...configuring the MultiDB component is unfortunately a very tricky business. The reason that it didn't work in your setup is because of the property "ImportConfig" in the mapper-collection on PersistenceMapperMultiDB. If this this property is false (as it was in your project) the MultiDB component will ignore the settings in the "child mappers" (the ones configured in the collection) and rely only on the config that it can find in the "RuntimeMappingProvider" property of its own (where you would normally specify a "FileMappingProvider"-component and then specify the entire mapping as an XML-file).
Another drawback of the MultiDB component is that it doesn't handle CreateSchema or Evolve very nicely. It was designed to support the case when you have multiple legacy databases that you need to access, and not when you want to generate the database schema from ECO.
In general, if you already have data in multiple databases, you would normally be better off to use separate models / ecospaces for them. The only advantage of having the two models in the same ecospace is if you have relations between classes in the two models, but even then, I don't think it is worth the trouble of configuring the MultiDB component, I would probably settle for access-methods between the two models.
If you don't already have multiple legacy databases I would definately not recommend splitting your data into multiple databases if it can be avoided."
Therefore now I use for each separate DB - separate model and EcoSapce class.
seg
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2011-04-13 12:29:45
Posts: 75,
Visits: 544
|
|
seq, thanks,
but i found the bug, now my test app run 
the overall process of building MultiDB app:
1. DomainModel: that will resides in defferent database must be de designed in separate packages.
2. I use xml for mapping files, for each persistence.
3. configure MultiDB to load configuration for each database connection.
4. we need apply patch to avoid bug.(will post solution and bug ASAP)
5. for creating database i use ecospace filled with needed packages. i.e. it can be one ecospace or more. only for generating databases and ormapping
6. after applying patch(code fix) data loads and saves into different databases.
7. for connecting entities in different databases i think better to use derived settable associations.
i have sample project but don't hink i can to upload this files here, so you(anyone) can ask it i send it by email or somehow.
vedmalex [at] gmail [dot] com
Alex
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2011-04-13 12:29:45
Posts: 75,
Visits: 544
|
|
i've posted bug report and sample solution is there.
http://magpie.no-ip.com/mantis/view.php?id=900
Alex
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2011-04-13 12:29:45
Posts: 75,
Visits: 544
|
|
Hi All,
here is fixed MultiDB Persistence Mapper.
Alex
|
|
|
|