How to get data from existing table? - orchardcms

I have a simple table without any dependencies in my database, and a little app which uploads files to storage and saves the urls in this table.
Finally I need a content part, where I can select a file (by name in DDL for example) and save in my content part record table (created via migrations). DDL columns - records from my existing table.
And I want to get access to this data, but I can't :(
According to this answer I tried to do something like that in my custom content part driver:
private readonly IRepository<MyExistingTableModel> _repo;
public MyCustomContentPartDriver(IRepository<MyExistingTableModel> repo)
{
_repo = repo;
}
MyExistingTableModel - model which name and fields identically with DB table.
MyCustomContentPartDriver - my content part, where I want to show data from my table (for selecting file and show it at the view page).
I already read a lot of Orchard CMS tutorials, but I feel that I have missed something simple and important.

Related

Create Data Factory Dataset in a specific Azure DevOps branch rather than directly in Data Factory

While trying to build an ADF pipeline that generates datasets within Data Factory, I ran into an interesting issue. Or maybe I misunderstand some components completely, in which case I'd happily be educated.
I basically read some meta data from a SQL Database table which determines which source system, schema and tables I should pull new data from. The meta data is stored within a bunch of variables, which then feed a Web Request that attempts to generate a new Data Source as per the MS documentation. Yes, I'm trying to use Azure Data Factory to generate Azure Data Factory components.
The URL to create the DataSet and the JSON Body for the request are both generated using #Concat and a number of the variables. The resulting DataSet is a very straightforward file that does not contain references to the columns, but just the table schema and table name. I generated these manually before, and that all seems to work brilliantly. I basically have a dataset connected to the source system, referincing the table from the meta data.
The code runs, but the resulting dataset is directly published, as opposed to being added in my working branch. While this should not be a big issue once I manage to properly test everything, ideally the object would be created in my working branch (using Azure DevOps, thus a local file).
My next thought was to set up a linked service to my local PC, and simply write the same contents as above there. My challenge seems to be that I essentially am creating a file out of nothing. I am trying to use a Copy Data component, and added an empty placeholder file to act as a source.
I configure the sink with Dynamic Content for Copy Behavior, and attempted to add the JSON contents there. This gets the file created, but it's unfortunately empty. I also attempted to add a new column to the source with the data being the same contents.
However, seeing the file to be used as a sink doesn't exist, a mapping error will occur. Apart from this, I'd not want a column header to be written; just the dynamically created contents.
I'm not sure how to continue with this. I feel I'm very close to achieving my goal, but cannot seem to take this final hurdle.
Any hints or suggestions would be very welcome.

Read a table from Kentico database which was not declared as 'custom table'

My question is pretty simple. I am working on Kentico 9 with its SQL Server database which contains several tables which had been added directly from the SQL Management Studio by an external contractor. The fact is that those tables are being used to store custom content which will be displayed for a site, but, in the code they don't have the code for making queries. I mean, they don't have Info and Provider classes.
https://docs.kentico.com/display/K82/Retrieving+database+data+using+ObjectQuery+API
According with this, all tables into the Kentico database can be accessed by invoking methods on these classes, but I don't have it this time.
Something like this, it will not work if I use my table name:
var user = UserInfoProvider.GetUserInfo("administrator");
var items = CustomTableItemProvider.GetItems("MyTable")
.TopN(10)
.WhereEquals("ItemCreatedBy", user.UserID)
.OrderBy("ItemCreatedWhen");
My question is:
can I query any table by its name?
One last thing:
I cannot declared those table as "custom table" because it seems to be a bug in the CMS.
Or you can pull data using your own SQL query:
var ds = ConnectionHelper.ExecuteQuery("select ....", null, QueryTypeEnum.SQLQuery);
Nevertheless I would recommend to create a custom class inside a custom module (much more robust than custom tables) instead and use the generated Info and InfoProvider classes to get and manipulate data.
I think an object has to be registered within the system (created through Kentico UI or API) in order to be pulled from DB with object query.
So I'd choose one of the following options:
Use Entity Framework or something similar to work with that data
Create appropriate custom tables or even custom module and push data there. Not sure why you can't create a custom table... What is an error you're getting?
If you need to present data on the UI only (without processing on the back end) - use just custom queries
Hope this helps.
If you are accessing in code then you could do it the good old fashioned way. If you want to pull data from the database to display on the website you could also do so by creating a custom query and using a transformation to display the fields, then use a repeater on the page to display the transformed data. Alternatively you can use a SQL datasource with a basic repeater, but you still have to create a transformation to display the data. Both methods allow you to access the data in the tables from within the CMS UI, no need to touch any code behind.
If your objective is to read data from these database tables to transform on webpage e.g. using CMS Repeater webpart, you can simply create custom query(s) in Kentico itself and load data using it. You can find the detail here on how to create custom custom queries and load data using it.
On the other hand you can also write your custom classes and define the custom methods where you can pull data using your own SQL query like this:
var ds = ConnectionHelper.ExecuteQuery("select ....", null, QueryTypeEnum.SQLQuery);
Lastly I don't think there should be any issue to create custom table instead of those direct DB tables, only thing we have to ensure code name of custom table should be unique means don't try to use exact same name because it'll cause exception due to same table name already exist in DB. You can please share exception you getting while creating custom table so that I can help you out further.

Orchard Content Parts that Don't Store Information in the Database

I'm trying to create a content part in Orchard that will perform a request to a web server and display the results of the request. The problem I'm running into is that my part requires no user input and thus I have left the part and part record classes empty. I have a Migrations.cs file that adds a description to the part and makes it attachable as well as creates a content item with the part attached to it. When I go to create a new instance of my content type it tries writing to the database and fails. How do you create a content part in orchard that doesn't try to save to the database? Thank you.
The actual error I receive is:
null id in Orchard.ContentManagement.Records.ContentTypeRecord
I'm pretty sure you don't need to create new table since there are many parts which don't have any in Orchard. Try to remove MyCustomPartRecord.cs and change MyCustomPart.cs
public class MyCustomPart : ContentPart<MyCustomPartRecord>
to
public class MyCustomPart : ContentPart
Then just add driver and view and you should be good without extra tables ... In theory :D
The answer to my problem is even when your part ins't actually saving anything in the database you still need to include a table for the part so it can store the id. I just added the following to my Migrations.cs file and it fixed the problem.
SchemaBuilder.CreateTable("MyCustomPartRecord",
table => table
.ContentPartRecord()
);

Custom Metadatafield in Document and Web content in Liferay

I want a metadata field getting values from database record. This metadata field should be added to document.
Can anyone provide a solution to my requirement.??
I presume you are using Liferay 6.1.
Web Content Structures
As for Web Content, you could programmatically create a JournalStructure (see JournalStuctureLocalServiceUtil) and populate the list of possible values for your structure field with values coming out of the database. You can put this "import code" inside a batch job, so your structure field and the values inside the external database are always in sync.
Document Metadata
How to do this with Metadata Sets is probably more interesting, as not only Dynamic Data Lists and Documents & Media use this in Liferay 6.1; as of 6.2, Web Content structures will utilize the same metadata API in favor of the old Journal API.
For this to implement, check out the xsd column of the DDMStructure table. It has more or less the same format as the XML for a JournalStructure, however there are more options available. Use DDMStructureLocalServiceUtil#addStructure to add such a new structure. Again, run this inside a batch so you always have the latest external DB values.

Orchard CMS - How to manage new fields for custom module widget with database?

I've been working with a custom module that has a widget with some fields stored in the DB. I added a new non-required field to the widget and a corresponding field in the database is not being added. What's the best way to handle this type of change?
I can manually add a field in the dev database to match it, but this is unrealistic for 50 some odd production tenant sites.
To expand on #Bertand's answer a little, you don’t need to create database columns when you add fields (Boolean Field, Text Field, Media Picker Field etc) to content parts because the database structure for storing fields is already in place in the database.
Fields are stored as serialized XML against the content part. All of my records are stored in the Orchard_Framework_ContentItemVersionRecord table (there’s a similar table Orchard_Framework_ContentItemRecord, but that doesn’t appear to be used.
The XML is essentially of the format:
<Data>
<SomePart>
<SomeFieldName SomeFieldProperty=”value”
SomeOtherProperty=”value”>FieldValue</SomeFieldName>
</SomePart>
<SomeOtherPart>
<SomeOtherFieldName>FieldValue</SomeOtherFieldName>
</SomeOtherPart>
</Data>
So, for example you might have something like this:
<Data>
<PicturePart>
<picture AlternateText="" Class="" Style="" Alignment="" Width="1219"
Height="709">~/Media/Default/images/greatPicture.jpg</picture>
</PicturePart>
<PictureType>
<ExtraDescription>It’s a great picture!</ExtraDescription>
</Pictureype>
</Data>
Orchard uses the information from the Settings_XXXRecord tables to determine the types of the fields when it’s deserializing them back from the database.
All of this is why, as Bertand says here, fields are easier to create, but harder to query.
Looking at the solution you've posted, it looks like you're adding custom columns, rather than Orchard Fields. If this is what you're trying to do, then it seems like something you should be doing in a datamigration for your module by using AddColumn, as described here. This would look something like:
public int UpdateFrom1() {
SchemaBuilder.AlterTable("TABLE_NAME", table => table
.AddColumn<int>("mynewcolumn")
.AddColumn<string>("mynewcolumn2")
);
return 2;
}
I'm not sure if it's the ideal solution, but running an sql script that manually adds the columns to the module table for all tenants sites seems to do the trick okay. Luckily I setup all my sites to exist in the same database!
SELECT 'Alter table ' + TABLE_NAME + ' Add mynewcolumn int null,
mynewcolumn2 nvarchar(15) null' FROM INFORMATION_SCHEMA.TABLES WHERE
TABLE_NAME LIKE '%the_suffix_my_module_puts_for_a_tenant'
A field is not supposed to add a column in the database. By design.

Resources