views:

730

answers:

1

I have two classes

public class Document 
{ 
    public virtual int Id { get; set; } 
    public virtual IList<File> Files { get; set; } 
} 
public class File 
{ 
    public virtual int Id { get; protected set; } 
    public virtual Document Document { get; set; } 
}

with the following convention:

public class HasManyConvention : IHasManyConvention 
{ 
    public bool Accept(IOneToManyPart target) 
    { 
        return true; 
    } 
    public void Apply(IOneToManyPart target) 
    { 
        target.Cascade.All(); 
    } 
}

and these mapping overrides

public class DocumentMappingOverride : IAutoMappingOverride<Document> 
{ 
    public void Override(AutoMap<Document> mapping) 
    { 
        mapping.HasMany(x => x.Files) 
            .Inverse() 
            // this line has no effect
            .Cascade.AllDeleteOrphan(); 
    } 
} 

public class FileMappingOverride : IAutoMappingOverride<File> 
{ 
    public void Override(AutoMap<File> mapping) 
    { 
        mapping.References(x => x.Document).Not.Nullable(); 
    } 
}

I understand that I need to make an IClassConvention for Document to change the cascade behaviour, however I can't get this to work! If i do this:

public class DocumentConvention : IClassConvention 
{ 
    public bool Accept(IClassMap target) 
    { 
        return target.EntityType == typeof(Document); 
    } 
    public void Apply(IClassMap target) 
    { 
        target.SetAttribute("cascade", "all-delete-orphan"); 
    } 
}

I get: "The 'cascade' attribute is not declared."

If i do this:

public class DocumentConvention : IClassConvention 
{ 
    public bool Accept(IClassMap target) 
    { 
        return target.EntityType == typeof(Document); 
    } 
    public void Apply(IClassMap target) 
    { 
        target.HasMany<Document, File>(x => x.Files) 
            .Inverse() 
            .Cascade.AllDeleteOrphan(); 
    } 
}

Then I get:

"Duplicate collection role mapping Document.Files"

so i added:

mapping.IgnoreProperty(x => x.Files);

to my document mapping, but then Files is always empty. What am I doing wrong? How can I override the cascade rule for a single HasMany relationship? Thanks Andrew

P.s. Sorry for the cross post with this but I need to get this solved asap.

A: 

I know this was forever ago (in computer time) and you might have already solved this. In case you haven't or someone else with a similar question sees this, here goes:

I think you need to create a class that implements IHasManyConvention. IClassConvention modifies an IClassMap (the <class> element) target. cascade is not a valid attribute for <class> so that accounts for the first error. On your second attempt, you were re-mapping the collection, resulting in the "duplicate collection" error.

IHasManyConvention targets an IOneToManyPart, upon which you should be able to call Cascade.AllDeleteOrphan() or just SetAttribute("cascade", "all-delete-orphan") if the former didn't work for some reason.

EDIT

Sorry, I missed that you already had a IHasManyConvention. Since you want to override your convention for just one type, you should just change the Accept method on your convention for that type. Instead of return true;, pull in what you had on your DocumentConvention:

return target.EntityType == typeof(Document);

I believe that OneToManyPart.EntityType references the containing entity type (i.e. Document).

Stuart Childs

related questions