Accessing data fails. Please help

Topics: Writing modules
Oct 5, 2011 at 8:46 PM

Hi all,

I just cant get CRUD actions to work in Orchard.... this is what I have:

  public class ChatMessagePartRecord : ContentPartRecord
    {
        public virtual string Message { get; set; }
        public virtual DateTime TimeStamp { get; set; }
        public virtual string UserName { get; set; }
    }

    public class ChatMessagePart : ContentPart<ChatMessagePartRecord>
    {
        [Required]
        public string Message
        {
            get { return Record.Message; }
            set { Record.Message = value; }
        }
        [Required]
        public string UserName
        {
            get { return Record.UserName; }
            set { Record.UserName = value; }
        }

        [Required]
        public DateTime TimeStamp
        {
            get { return Record.TimeStamp; }
            set { Record.TimeStamp = value; }
        }
    }


    public class ChatMessageHandler : ContentHandler
    {
        public ChatMessageHandler(IRepository<ChatMessagePartRecord> repository)
        {
            Filters.Add(StorageFilter.For(repository));
        }
    }

public class Migrations : DataMigrationImpl
    {
        public int Create()
        {
            SchemaBuilder.CreateTable("tb__ChatBox_ChatMessagePartRecord", table => table
                .ContentPartRecord()
                .Column("Message", DbType.String)
                .Column("TimeStamp", DbType.DateTime)
                .Column("UserName", DbType.String)
            );

            ContentDefinitionManager.AlterPartDefinition("ChatMessagePart",
                    builder => builder.Attachable());

            return 1;
        }
    }

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Orchard.Data;
using ChatBox.Models;
using Orchard;
using Orchard.Themes;
using Orchard.ContentManagement;

namespace ChatBox.Controllers
{
    [Themed]
    public class HomeController : Controller
    {
        private readonly IRepository<ChatMessagePart> _chatMessageRepository;
        private IOrchardServices _services;
        private IContentManager _contentManager;

        public HomeController(IRepository<ChatMessagePart> chatMessageRepository, IOrchardServices services, IContentManager contentManager)
        {
            _contentManager = contentManager;
            _services = services;
            _chatMessageRepository = chatMessageRepository;
        }

        public ActionResult Index()
        {
            ChatMessagePartRecord part = new ChatMessagePartRecord()
            {
                Message = "123132",
                TimeStamp = DateTime.Now,
                UserName = "UserName"
            };

            // Fails: "attempted to assign id from null one-to-one property: ContentItemRecord"
            _chatMessageRepository.Create(part);
            _chatMessageRepository.Flush();

            // Fails: "could not execute query <...>"
            var collection = _chatMessageRepository.Table.ToList();
            
            // Fails: Returns no values although I've added 1 record trough Sql Management Studio
            var list  = _contentManager.Query<ChatMessagePart>().List();

            return View();
        }
    }
}
 In the last code snipped, I've put three comments starting with "Failed". Can someone tell me what I'm doing wrong? I've read most of the Tutorials on de orchardproject website and I can't seem to find the right way to do this.
Many thanks in advance.
Coordinator
Oct 5, 2011 at 8:50 PM

If this is going to be used on its own, without being attached to a content item, don't use a part, only the record.

Oct 6, 2011 at 7:19 AM

Hi BetrandLeroy,

Thanks for your reply. What do you exactly mean with saying that?

Should I use ChatMessagePart only? Or drop both the ChatMessagePart & ChatMessagePartRecord and create a new poco entity.

Oct 6, 2011 at 1:48 PM

I think what Betrand is saying is that you are trying to use IRepository with your ChatMessagePart type, when you should be using it with ChatMessagePartRecord. So in your constructor you should change the parameter from IRepository<ChatMessagePart> to IRepository<IChatMessagePartRecord>.

The other part of this though, is that if you're just going to use IRepository directly, you don't need the ChatMessagePart class at all. However, based on your last line of code where you're trying to query with the ContentManager it appears you want to actually create a content item. In that case, you shouldn't use IRepository to do it, you should use the ContentManager to create a content item.

Coordinator
Oct 6, 2011 at 7:18 PM

A part is only allowed to exist attached to an item. If you have no item, there is no sense in using a part at all. Remove it, and use only records in that case.

Oct 8, 2011 at 7:16 AM

Hi all,

Thanks for your replies. I've read this article (again): http://www.orchardproject.net/docs/Basic-Orchard-Concepts.ashx#Orchard_concepts_31 and I understand that I am using it wrong. Is there any tutorial about orchard and working with data?

My goal is to create a chatbox controller where users can add text lines to one table in the database. Thats it :).

Many thanks in advance.

Coordinator
Oct 10, 2011 at 8:25 PM

Unfortunately no, but you're pretty close once you remove the part.

Oct 18, 2011 at 8:24 PM

I've manged to make it work!

In the \Models folder, I've created a model:

    public class ShoutMessage
    {
        public virtual int Id { get; set; }
        public virtual string Message { get; set; }
        public virtual string Username { get; set; }
        public virtual DateTime TimeStamp { get; set; }
    }
(Hence that I don't inherit from anything)
Then I've manually(!) created my own table in the Orchard database [modulename]_[tablename]. I really thought that this should be managed using data migrations. Perhaps it should.. not sure, but this works.
Then in the controller I can succesfully run:
IRepository<ShoutMessage> _repository;
        public HomeController(IRepository<ShoutMessage> repository)
        {
            _repository = repository;
        }

        public ActionResult Index()
        {
            _repository.Create(new ShoutMessage()
            {
                Message = "Test",
                Username = User.Identity.Name,
                TimeStamp = DateTime.Now
            });

            var result = (from c in _repository.Table
                         select c);

            return View();
        }
Thank you all for your support/input.
Oct 25, 2011 at 2:10 AM
tweek82 wrote:

I've manged to make it work!

In the \Models folder, I've created a model:

    public class ShoutMessage
    {
        public virtual int Id { get; set; }
        public virtual string Message { get; set; }
        public virtual string Username { get; set; }
        public virtual DateTime TimeStamp { get; set; }
    }
(Hence that I don't inherit from anything)
Then I've manually(!) created my own table in the Orchard database [modulename]_[tablename]. I really thought that this should be managed using data migrations. Perhaps it should.. not sure, but this works.
Then in the controller I can succesfully run:
IRepository<ShoutMessage> _repository;
        public HomeController(IRepository<ShoutMessage> repository)
        {
            _repository = repository;
        }

        public ActionResult Index()
        {
            _repository.Create(new ShoutMessage()
            {
                Message = "Test",
                Username = User.Identity.Name,
                TimeStamp = DateTime.Now
            });

            var result = (from c in _repository.Table
                         select c);

            return View();
        }
Thank you all for your support/input.

 

 

Greate, I was traped same thing one day. Thanks that a lot.

BTW: In English the "that" & "this" which is meaning the part before the word?