CodePlexProject Hosting for Open Source Software
I have three main questions about accessing the data in the database using Orchard.
1) How do you access a specific row in your database from the code ?
2) How do you create a module in which you field are correctly link to the database. I tried building the module simpleCommerce. The new module is showed in my administration page but the sku and the price fields aren't seem to be connected to
the database. When I type in values and save, nothing is written in the database. So if you have another tutorial which I could base on.
3) Is there a way, in a module, to get the entire list of a table from the database ? I want to be able to populate a list and show this to the user. Is there also a way to get a list of a table data from many different table (in separate list) ? because
it seems Orchard has been designed to work only on one module at a time.
1) You can use IRepository<TPART> and query for what you need. Or you can use ISessionLocator to give you access to the current NHibernate session and do everything that NHibernate allows, and if you still want more power you can probably access the
DbConnection instance in NHibernate and perform SQL queries.
2) Have you added a ContentHandler and set the Filter.Add(Storage.For<IRepository<OfYourPart>>()) ?
3) Orchard has been designed to work with Content Items. A content item is made up of ContentParts, and ContentFieds. ContentPart has a Record, which maps to a table in the DB. ContentField has a storage, the storage saves tha data as XML in the ContentFieldTable
( not sure about the table name ).
If you want the entire list of db tables, than you're probably required to use 1) NHibernate session directly or 2) DbConnection associated with NH session and execute a Select * from INFORMATION_SCHEMA where TYPE='u'. You can find the query online
since it's pretty basic. I don't know what you need to execute on SQL CE.
Thanks for answering !
1) But how do you use IRepository<TPART> and ISessionLocator ? Is there a tutorial somewhere for that ? The only one I've found so far are on MVC pattern but what they say don't always compile on Orchard. I don't think i need to
send sql query. I want a simple row of data.
2) Yes I did. I followed thoroughly Orchard's tutorial (The one about writing a SimpleCommerce module) but it still doesn't work.
3) I didn't want something really fancy. I just want to be able to do a king of "select * from table" on 2 or tree tables and show the result.
First, see the following documentation which covers some common data access scenarios:
For the code you've written that doesn't work, it might help if you post your code here and maybe we can see what the problem is!
In your controller, or driver you just set a dependency on the controller for IRepository<MyRecord> ( sorry I wrote TPart there :P ). If you don't have a class extending Record, then you need to use ISessionLocator. There is no documentation AFAIK,
you just get the source and search for it in the Solution. You should see how the actual Repository implementation uses it.
It should be pretty straight forward, ISessionLocation gives you a property that contains the current NHibernate session. If you don't have an entity defined in a namespace ending with Records or Models then FluentNHibernate will not know it needs to pick
it up, and you'll have to fall back to HQL queries.
However if you are following the standard way, that is writing a Record, and a Part. And having the Part added to a ContentType. Then, you should be able to just use the ContentManager.Query<TPart>, where TPart is the concrete type you've written.
You should probably browse through the documentation a bit more, and have a look at the Blog module.
The thing is; it's a whole module so there are a lot of different files. Isn't a way to enclose file on this forum ? But anyway the code I put is the exact same thing as writtent in this tutorial:
Thanks for your tutorial. I am going through it. Hope I find what I need.
I went through the tutorial. It's really useful for teaching how to create related table on Orchard but I didn't find what I was looking for. I just want to be able to access a table and get all the row from that table but the tutorial doesn't show how to
do that.
Using IRepository seems a good idea. How do you create and use a IRepository dependency ? Do you have a snippet of code I could base on ?
You don't have to create anything except the record class & migration. Just get a dependecy to IRepository<YourRecordType> injected into your class and we'll build one for you.
What do you me by "we" ? You want me to send you my model and migration code ? By injecting a dependency do you mean creating a field of tye IRepository in my model class ?
No :) You will still have to write your own code. What I mean is that just by taking a dependency on IRepository<Something>, the framework will provide an implementation of the repository.
Lol okay. And where do I inject that dependency ? In my controller ? Or Driver ?
Wherever you need to use it. That would typically be your controllers and drivers, yes.
Where do I get an instance of the object ?
What object?
You inject into your constructor. So here's an example on a controller:
public class MyController : Controller {
private readonly IRepository<MyRecord> _myRecordRepository;
public IOrchardServices Services { get; set; }
public MyController(
IRepository<MyRecord> myRecordRepository,
IOrchardServices services
) {
_myRecordRepository = myRecordRepository;
Services = services;
}
}
So the constructor will automatically get called with instances of the objects, you don't need to worry about it.
Okay I got an instance of the IRepository but it throws an error each time I use it. For instance: It throws the following error on the call of the method  35: {
Line 36: get { return Record.Path; }
Line 37: set { Record.Path = value; }
Line 38: }
Line 39:
Line 35: {
Line 36: get { return Record.Path; }
Line 37: set { Record.Path = value; }
Line 38: }
Line 39:
Here's the code I put in my controller:
[
public
class
HomeController
:
Controller
{
private
readonly
IRepository<FileU
> _myRecordRepository;
public
IOrchardServices
services { get;
set
; }
public
HomeController(IRepository<FileU
> myRecordRepository,
IOrchardServices
services)
_myRecordRepository = myRecordRepository;
this
.services = services;
}
//ListU listFile = new ListU();
public
ActionResult
Index()
_myRecordRepository.Create(
new
FileU
{ Path = "C:\\Salut",
Name = "Essais.txt",
Tag = ""
});
return
View("UploadModule"
);
Here's
my FileU.cs code:
public
ContentPartRecord
//public virtual int ID { get; set; }
; }
>
Record.Tag; }
Required
]
Name
Record.Name; }
Path
Record.Path; }
The problem there is that you're implementing a ContentPartRecord but trying to access it like an ordinary (non-content) record.
These are the two distinctions:
- ContentPartRecord is used when you have data and functionality that you want to add to
content items, via a ContentPart. You cannot use IRepository to access content parts - you have to go through IContentManager.Get(...) or IContentManager.Query(...) to retrieve the whole content item. You can perform querying
on your ContentPartRecord using Where<MyContentPartRecord>(...).
- For all other data access, you implement your model as a POCO class, and say if it were called SomeModelRecord you'd use IRepository<SomeModuleRecord> to access the table directly. The ContentPart<TContentPartRecord> pattern is
only for content parts, for any other database access you just deal with the record/model class directly.
Which is the best to use ? I want to build a module allowing the administrator to enter file and show it to users depending on their rights. I don't quite understand the difference between a content part, a content Item and a widget.
Does it make sense to add this to existing content types? If yes, make a part. If no, make a plain record.
I think I will make it a record. It's strange because the code I wrote was based on the simpleCommerce module in Orchard tutorial. I have never been able to make it work though. Maybe that's why it didn't work. I inherited from the wrong class. So how do
I implement POCO class ? In which package is this ?
Just use that record class everywhere and don't inherit from ContentPartRecord. Don't implement a part. That's it. Make everything virtual and have an Id property.
le_programmeur wrote:
Which is the best to use ? I want to build a module allowing the administrator to enter file and show it to users depending on their rights. I don't quite understand the difference between a content part, a content Item and a widget.
Content Item: A piece of content, composed of many Content Parts
Content Part: A chunk of functionality, business logic, and templates - it can be attached to any Content Types which are used to define actual Content Items.
Widget: Actually just a Content Item, with a special setting of Stereotype="Widget" (vs "Content" for a normal item), and also a Content Part called
WidgetPart. A content type matching both those criteria can be added to layout zones, via the Layers system.
Hope that helps :)
Now; just regarding the module you're building (a simple Document Management system if I understand correctly). You could perhaps save yourself quite a bit of time by using some existing modules! Firstly, there's Piotr's Content Authorization system which
allows you to apply authorisation rules for viewing content. Then, there's a project I'm working on called Media Garden - it improves on Orchard's basic media functionality, by creating each uploaded file as a proper Content Item complete with its own page/URL,
whatever other parts you want to add, and an appropriate viewer for the type of file - in the case of binary document files this would just be a download link (although you could add other types of viewers for specific formats). Combined with Piotr's security
system this would easily allow you to restrict who can view each file. Finally, there's a module I'm working on called Quanta, which is a system for granting users and groups of users specific roles over individual items.
Actually I was going to be implementing a proper integration between all three of those modules anyway, so yes what you'd have is a roles-based document management system. If you wanted to work with me on that, it could be fully working very soon - the vast
majority of the work is already there, and I know there are some particularly tricky aspects to what you're doing!
@sharpoverride : you are saying you can "probably access the DbConnection instance in NHibernate and perform SQL queries"... how can you do that?
I'm always getting "No CurrentSessionContext configured (set the property current_session_context_class)!" error when trying to access
_sessionFactoryHolder.GetSessionFactory().GetCurrentSession() ?
Are you sure you want to delete this post? You will not be able to recover it later.
Are you sure you want to delete this thread? You will not be able to recover it later.