Reputation: 3735
I have created a module that i want to collect some simple data in Orchard's database, so i have created model, migration and handler for it:
Models/StatePartRecord.cs
:
namespace Address.Models
{
public class StatePart : ContentPart<StatePartRecord>
{
public int Id
{
get { return Record.Id; }
set { Record.Id = value; }
}
public string StateName
{
get { return Record.StateName; }
set { Record.StateName = value; }
}
}
}
Models/StatePartRecord.cs
:
namespace Address.Models
{
public class StatePartRecord : ContentPartRecord
{
public virtual int Id { get; set; }
public virtual string StateName { get; set; }
}
}
Migrations.cs
:
namespace Address
{
public class Migrations : DataMigrationImpl
{
public int Create()
{
SchemaBuilder.CreateTable("StatePartRecord", table => table
.ContentPartRecord()
.Column<string>("StateName")
);
return 1;
}
public int UpdateFrom1()
{
ContentDefinitionManager.AlterPartDefinition("State", part => part
.Attachable());
return 2;
}
}
}
Handlers/StatePartHandler.cs
:
namespace Address.Handlers
{
public class StatePartHandler : ContentHandler
{
public StatePartHandler(IRepository<StatePartRecord> repository)
{
Filters.Add(StorageFilter.For(repository));
}
}
}
Services/MyService.cs :
namespace Address.Services
{
public class AddressService : IAddressService
{
...
public void InsertState(Models.StatePartRecord state)
{
_stateRepository.Create(state);
}
...
}
now in written service class for my module, when i try to create an item and save it in database it trows an exeption:
attempted to assign id from null one-to-one property: ContentItemRecord
Note that _stateRepository
is a IRepository<StatePartRecord>
typed injected object.
what is wong?
Upvotes: 2
Views: 4967
Reputation: 2888
This is because ContentPartRecord has a ContentItemRecord property that points to the ContentItemRecord corresponding to the content item the ContentPartRecord's Part is attached to.
You don't have to manage part records directly: Orchard services (mainly ContentManager) does this for you. Even if you want to modify records on a lower level you should do this through ContentManager (by injecting an IContentManager). Only manipulate records directly if they're just "plain" records you use to store non-content data, i.e. that aren't ContentPartRecords.
// MyType is a content type having StatePart attached
var item = _contentManager.New("MyType");
// Setting parts is possible directly like this.
// NOTE that this is only possible if the part has a driver (even if it's empty)!
item.As<StatePart>().StateName = "California";
_contentManager.Create(item);
Upvotes: 3