开发者

Why does adding this line mess up my NHibernate mapping?

开发者 https://www.devze.com 2023-02-28 00:26 出处:网络
I have a very simple ClassMap public class ContentMap : ClassMap<Content> { public ContentMap() { // Basic property mapping

I have a very simple ClassMap

public class ContentMap : ClassMap<Content>
{
    public ContentMap()
    {
       // Basic property mapping

       // Parent property mapping
       References(x => x.Category).Column("CategoryId");
    }
}

Using this, my mappings work perfectly fine and the Category property is not null.

If I try to add this line below the first reference

References(x => x.LastActive).Column("LastActiveSubCategoryId");

My mappings go wrong.

If LastActiveSubCategoryId is null, Category maps fine. If it is not null, LastActiveSubCategoryId will be set but then CategoryId is null.

The actual properties themselves are simple

public virtual Category Category { get; set; }

public virtual SubCategory LastActive { get; set; }

There is nothing complex in the Category or SubCategory mappings either. They look very similar to the ContentMap class (with only one reference line)

Any idea what would cause this behavior? Can I only use one Reference?

Update

I've looked at the SQL and this is what appears to be happening, hopefully someone can help me understand why.

The Content entity gets inserted into the database just fine with the CategoryId and LastActiveSubCategoryId null.

The Category entity gets inserted and then an update statement updates the Content, only updating the CategoryId field and nothing else.

If there was no SubCategory, everything would be fine at this point.

If there is a SubCategory, then a few statements later it is inserted and then the Category gets updated. In the update statement a few different values are being modified (some that don't need to be a开发者_开发问答s they haven't changed since the insert), including the CategoryId and SubCategoryId. Except now CategoryId is null and LastActiveSubCategoryId is not.

So why would CategoryId be null on the update?

Update 2

The code I'm using to actually insert the objects is just for some basic tests at this point. These are the relevant bits of code:

Category category = new Category();
dao.Save(category);

Content content = new Content();
category.AddContent(content); // Adds it to a list, like in the tutorial mBotros posted
dao.Save(Content);

SubCategory subCategory = new SubCategory();
content.AddSubCategory(subCategory);
dao.Save(subCategory);

// On the Content class
public virtual void AddSubCategory(SubCategory subCategory)
{
   SubCategories.Add(subCategory);
   LastActive = subCategory;
}


There is a circular reference in your database schema, which can make inserting rows tricky.
Content references SubCategory, and SubCategory references Content. If you were to try to insert rows using plain old SQL, you would not be able to do this:

/* this line does not work because SubCategory 2 does not exist yet */
insert into Content (Id, LastActiveSubCategoryId) values (1, 2);
insert into SubCategory (Id, ContentId) values (2, 1);

You would instead have to do something like this:

insert into Content (Id, LastActiveSubCategoryId) values (1, null);
insert into SubCategory (Id, ContentId) values (2, 1);
update Content set LastActiveSubCategoryId = 2 where Id = 1;

You need to keep this in mind when you are persisting your NHibernate entities. Modify AddSubCategory to not set LastActive. First save the two entities, then close the loop.

// ... code to save Category and Content, then...

SubCategory subCategory = new SubCategory();
content.AddSubCategory(subCategory); // modified to *not* set LastActive
dao.Save(subCategory);

content.LastActive = subCategory;
dao.Update(content);


You mention a LastActiveId that is not in the code you've shown.

Are you by chance trying to map a column as both a Reference and a scalar Property?

Update: either your code snippet is still incomplete, or you're missing the transaction/flush that will cause the updates to happen. Also, do you have both a collection (not shown) called SubCategories and a property called LastActive?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号