I am creating a module for use in DNN 7+ and would like to use DAL2 for data access but am having some problems selecting items from the database.
My code appears to be connecting to the database successfully but the queries that are generated by DAL2 do not include the names of the fields in the database table. I an running an SQL Server Profiler to watch what gets to the database and see queries that start with "SELECT NULL FROM Product...". I expect to see "SELECT * FROM Product..." or "SELECT ProductCode FROM Product..."
For the purposes of isolating the problem and being able to include a full code sample, I have worked my test down to the following: I have a Product.cs file:
using System.Web.Caching;
using DotNetNuke.ComponentModel.DataAnnotations;
namespace MyModule.Components
{
[TableName("Product")]
[PrimaryKey("productCode")]
[Cacheable("MYMODULE_Product_", CacheItemPriority.Default, 20)]
[Scope("productCode")] //different values here did not change the result.
public class Product
{
public string productCode;
}
}
I have a ProductRepository.cs file:
using DotNetNuke.Data;
namespace MyModule.Components
{
public class ProductRepository
{
private const string EXTERNAL_DB_CONNECTION_STRING = "MY_DB_CONNECTIONSTRING_NAME";
public Product GetProduct(string productCode)
{
Product t;
using (IDataContext ctx = DataContext.Instance(EXTERNAL_DB_CONNECTION_STRING))
{
var rep = ctx.GetRepository<Product>();
t = rep.GetById(productCode);
}
return t;
}
}
}
I use these two files in my view with the following code:
ProductRepository productRepo = new ProductRepository();
Product product = (Product)productRepo.GetProduct("MYCODE");
While running this code, I monitor using the SQL Server Profiler and see that the following query is executed:
exec sp_executesql N'SELECT NULL FROM [Product] WHERE [productCode]=@0',N'@0 nvarchar(4000)',@0=N'MYCODE'
I don't know why the select query above is selecting NULL. I am expecting a list of product fields from the Product.cs file, or the * character.
My database field definition (as seen from the tree view of the Microsoft SQL Server Management Studio) for the productCode is:
productCode(PK, varchar(50), not null)
I am connecting to an external database and the data is not connected with a specific module or portal. That is why I specify "productCode" as the Scope. I am not sure what the proper use of Scope is when the data is not tied to the portal or module. To make sure the problem was not connected to the Scope attribute in the Product.cs file I tested with the Scope variable set to "PortalId", "ModuleId", "productCode", and "Nothing". All of these values resulted in the same query showing up in the SQL Server Profiler.
I also tested by removing the Scope attribute entirely. When the Scope attribute was not included I saw the following query in the SQL Server Profiler:
SELECT NULL FROM [Product]
I am not sure why the WHERE clause was removed when the Scope attribute was excluded, but that is what test results showed.
These tests with the Scope attribute lead me to believe it is not related to the "SELECT NULL" problem I am seeing but I wanted to include it here for completeness.
Can anyone help, why is this creating a select with NULL and how do I get it to select my data?
Thanks!
I found an answer but would like a little help understanding why this works. First, to get the data column to connect, I changed the Product.cs class to this:
using System.Web.Caching;
using DotNetNuke.ComponentModel.DataAnnotations;
namespace MyModule.Components
{
[TableName("Product")]
[PrimaryKey("productCode")]
[Cacheable("MYMODULE_Product_", CacheItemPriority.Default, 20)]
[Scope("productCode")] //tried different values here and nothing changed but excluding this caused more problems
public class Product
{
public string productCode { get; set; };
}
}
The difference here is the addition of the get and set accessors. This is confusing to me as I thought the previously used line
public string productCode;
would be functionally equivalent to
public string productCode { get; set; };
in this context. I thought 'get' and 'set' were not needed unless access to the variable was going to be limited to one of those operations, or if more extensive processing needed to happen while setting or getting the protected value.
Am I missing something in my understanding of get and set or am I understanding this correctly? Are the get and set only required here to be compatible with DAL2?