This is a migrated thread and some comments may be shown as answers.

Problem with N:M association (fluent mapping)

5 Answers 81 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
piotrekk
Top achievements
Rank 1
piotrekk asked on 19 Feb 2012, 06:39 PM
Hello,

I'm trying to define the model like this:
public abstract class Element
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public IList<Catalog> Catalogs { get; private set; }
    public Element()
    {
        Catalogs = new List<Catalog>();
    }
}
 
public class Catalog: Element
{
    public bool CanHoldCatalogs { get; set; }
     public IList<Element> Entries { get; private set; }
 
    public Catalog()
    {
        Entries = new List<Element>();
    }
}
 
//and of course, other classes inherited from Element

I'm making the mapping like this:
MappingConfiguration<Element> elementMap = new MappingConfiguration<Element>();
elementMap.MapType().ToTable("Elements");
elementMap.HasDiscriminator().ToColumn("class").HasColumnType("char").HasPrecision(10);
elementMap.HasProperty(p => p.Id).IsIdentity(KeyGenerator.Autoinc);
 
MappingConfiguration<Catalog> catalogMap = new MappingConfiguration<Catalog>();
catalogMap.MapType().Inheritance(InheritanceStrategy.Vertical).ToTable("Catalogs");
catalogMap.HasDiscriminatorValue("catalog");
 
catalogMap.HasAssociation(a => a.Entries).WithOpposite(o => o.Catalogs)
    .MapJoinTable("CatalogEntries", (c,e) => new {CatalogID=c.Id,ElementId=c.Id});


Model compiles without any errors, the database structure generated by OpenAccessContext looks good and I can do such operation:
var root = new Catalog {Name = "root"};
var home = new Catalog {Name = "home"};
root.Entries.Add(home);
 
context.Add(root);
context.SaveChanges();

Both 'root' and 'home' are correctly writed to the database, but nothing is saved to the join table, so there is no association created... :(

best regards
pk

5 Answers, 1 is accepted

Sort by
0
Accepted
Serge
Telerik team
answered on 22 Feb 2012, 02:04 PM
Hello Piotr,

 Make sure that you have called IsManaged on both sides of the association, this will ensure that all records inserted in both collection are correctly persisted in the database. You code should look something like: 

catalogMap.HasAssociation(a => a.Entries).WithOpposite(o => o.Catalogs)
    .IsManaged()
    .MapJoinTable("CatalogEntries", (c, e) => new { CatalogID = c.Id, ElementId = c.Id });
 
elementMap.HasAssociation(o => o.Catalogs).WithOpposite(a => a.Entries)
    .IsManaged();

I hope this helps. 

All the best,
Serge
the Telerik team
Telerik OpenAccess ORM Q1 2012 release is here! Check out what's new or download a free trial >>
0
piotrekk
Top achievements
Rank 1
answered on 22 Feb 2012, 03:39 PM
Hello Serge,

You are absolutely right! Everything work OK now. Thank you for support.

But testing my solution, I've found minor bug (?) in the fluent mapping N:M definition.
Assume, we have:
elementMap.HasAssociation(a => a.Catalogs).WithOpposite(o => o.Entries).IsManaged() //:)
.MapJoinTable("CatalogEntries",
     (element, catalog) =>
new { CatalogID = catalog.Id,ElementId = element.Id});
(Note the revers order of fields declaration in join table).
OpenAccess creates, as we can expect, the join table with two columns: 'CatalogID' and 'ElementID', but Element's IDs are put in column 'CatalogID' (and Catalog's IDs, of course, in 'ElementID'). Except that, everything work properly.

best regards
pk
0
Serge
Telerik team
answered on 22 Feb 2012, 03:51 PM
Hello Piotr,

 Are you sure that the catalog variable is in fact the one that represents the catalog object. Can you check its type and whether it is possible that they are switched. If that is not true, can you please send us the project to check this out in greater detail. 

If what you are saying is correct we might have a serious bug on our hands.

I am looking forward to resolving this issue with you. 

Regards,
Serge
the Telerik team
Telerik OpenAccess ORM Q1 2012 release is here! Check out what's new or download a free trial >>
0
piotrekk
Top achievements
Rank 1
answered on 22 Feb 2012, 04:17 PM
Hmm, I've tested this twice - with the same effect.
I'll send to you a small project as a support ticket.

regards
pk

PS. I hope I'm wrong - no one likes huge errors...
0
Serge
Telerik team
answered on 23 Feb 2012, 02:34 PM
Hello Piotr,

 I will post my reply here, so that it is available to the community, if they ever faced the same problem. 

Unfortunately this turned out to be a bug on our side, however it is not as grave as I initially thought. It is related to the fact the the identity is specified in the base class. We have added it to our internal issue tracker and you can expect a fix with the upcoming service pack. 

For the time being though, you can fix the behaviour by simply switching the order in which you define the join table columns, always put the one referencing the mapping configuration type first. 

Thank you for providing your solution it proved very helpful indeed.

Kind regards,
Serge
the Telerik team
Telerik OpenAccess ORM Q1 2012 release is here! Check out what's new or download a free trial >>
Tags
Development (API, general questions)
Asked by
piotrekk
Top achievements
Rank 1
Answers by
Serge
Telerik team
piotrekk
Top achievements
Rank 1
Share this question
or