Computed field in Servicestack ormlite error - c#

I couldn't make it work, I added the data annotation for a computed field using ServiceStack ormlite Sql server:
[Compute, Ignore]
public string FullName { get; set; }
The problem is that my LoadSelect<Employee>() method doesn't load the colunm FullName from a computed field. Why?
if I remove the [Ignore] it loads, but then when I use the.create() method to create a new record, it returns an error, probably because it tries to add a value for the FullName field.
Table
CREATE TABLE [dbo].[Employee](
[EmployeeId] [int] IDENTITY(1,1) NOT NULL,
[FullName] AS (concat(ltrim(rtrim([FirstName])),' ',ltrim(rtrim([LastName])))) PERSISTED NOT NULL,
[FirstName] [nvarchar](55) NOT NULL,
[LastName] [nvarchar](55) NULL,
[Username] [nvarchar](55) NOT NULL,
[Password] [nvarchar](55) NULL
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[EmployeeId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
Employee class:
[Schema("dbo")]
[Alias("Employee")]
public class Employee : IHasId<int>
{
[PrimaryKey]
[Alias("EmployeeId")]
[AutoIncrement]
[Index(Unique = true)]
public int Id { get; set;}
[Required]
public string FirstName { get; set; }
public string LastName { get; set; }
[Required]
[Index(true)]
public string Username { get; set; }
public string Password { get; set; }
[Compute, Ignore]
public string FullName { get; set; }
}
Get method:
public virtual async Task<IEnumerable<T>> Get<T>() where T : IHasId<int>
{
using (var dbCon = DbConnectionFactory.OpenDbConnection())
{
return await dbCon.LoadSelectAsync<T>(x => x);
}
}
Create method:
public virtual async Task<T> Create<T>(T obj) where T: IHasId<int>
{
using (var dbCon = DbConnectionFactory.OpenDbConnection())
{
// if there is an id then INSERTS otherwise UPDATES
var id = obj.GetId().SafeToLong();
if (id > 0)
dbCon.Update(obj);
else
id = dbCon.Insert(obj, true);
// returns the object inserted or updated
return await dbCon.LoadSingleByIdAsync<T>(id);
}
}

The [Ignore] attribute tells OrmLite you want it to ignore the property completely which is not what you want, you need to just use the [Compute] attribute to handle computed columns which I've just added a test for in this commit which is working as expected in the latest version of OrmLite, e.g:
db.DropTable<Employee>();
db.ExecuteSql(#"
CREATE TABLE [dbo].[Employee](
[EmployeeId] [int] IDENTITY(1,1) NOT NULL,
[FullName] AS (concat(ltrim(rtrim([FirstName])),' ',ltrim(rtrim([LastName])))) PERSISTED NOT NULL,
[FirstName] [nvarchar](55) NOT NULL,
[LastName] [nvarchar](55) NULL,
[Username] [nvarchar](55) NOT NULL,
[Password] [nvarchar](55) NULL
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED ([EmployeeId] ASC)");
var item = new Employee
{
FirstName = "FirstName",
LastName = "LastName",
Username = "Username",
Password = "Password",
FullName = "Should be ignored",
};
var id = db.Insert(item, selectIdentity: true);
var row = db.LoadSingleById<ComputeTest>(id);
Assert.That(row.FirstName, Is.EqualTo("FirstName"));
Assert.That(row.FullName, Is.EqualTo("FirstName LastName"));
row.LastName = "Updated LastName";
db.Update(row);
row = db.LoadSingleById<ComputeTest>(id);
Assert.That(row.FirstName, Is.EqualTo("FirstName"));
Assert.That(row.FullName, Is.EqualTo("FirstName Updated LastName"));
Which also works using the async API's in your Create() helper method, e.g:
var row = await Create(item);
Assert.That(row.FirstName, Is.EqualTo("FirstName"));
Assert.That(row.FullName, Is.EqualTo("FirstName LastName"));
row.LastName = "Updated LastName";
row = await Create(row);
Assert.That(row.FirstName, Is.EqualTo("FirstName"));
Assert.That(row.FullName, Is.EqualTo("FirstName Updated LastName"));
I'm assuming you're using an older version of OrmLite, if you upgrade to the latest version it should work.

Related

Inserting a record to Recursive Table with EF Core 6, identity table set ON

I have the following two tables
CREATE TABLE [Finance].[Account]
(
[AccountId] INT IDENTITY(1, 1) NOT NULL,
[Name] NVARCHAR(100) NOT NULL,
[AvailableBalance] DECIMAL(13, 4) NULL,
[CurrentBalance] DECIMAL(13, 4) NOT NULL,
[TypeId] INT NULL,
CONSTRAINT [PK_Account_Id]
PRIMARY KEY CLUSTERED ([AccountId] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY],
CONSTRAINT [FK_Account_Type]
FOREIGN KEY (TypeId) REFERENCES [Finance].[AccountType](AccountTypeId)
) ON [PRIMARY]
CREATE TABLE [Finance].[AccountType]
(
[AccountTypeId] INT IDENTITY(1, 1) NOT NULL,
[AccountTypeParentId] INT NULL,
[Name] NVARCHAR(100) NOT NULL
CONSTRAINT [PK_AccountType]
PRIMARY KEY CLUSTERED ([AccountTypeId])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY],
CONSTRAINT [FK_AccountType_Parent_AccountType]
FOREIGN KEY (AccountTypeParentId) REFERENCES [Finance].[AccountType](AccountTypeId),
) ON [PRIMARY]
With the following class structure
public class Account
{
public int AccountId { get; private set; }
public string Name { get; private set; }
public decimal AvailableBalance { get; private set; }
public decimal CurrentBalance { get; private set; }
public AccountType Type { get; private set; }
public void SetType(AccountType type)
{
if (type != null)
{
Type = type;
}
}
}
public class AccountType
{
public int AccountTypeId { get; private set; }
public string Name { get; private set; }
public int? AccountTypeParentId { get; private set; } = null;
public AccountType ParentType { get; private set; }
protected AccountType()
{
}
private AccountType(int accountTypeId, string name)
{
AccountTypeId = accountTypeId;
Name = name;
}
public static AccountType CreateAccountType(string name)
{
return new AccountType(0, name, DateTime.UtcNow);
}
public void SetParent(AccountType type)
{
ParentType = type;
}
}
I am using following mapping in EF Core 6
modelBuilder.Entity<AccountType>(entity =>
{
entity.ToTable("AccountType", schema: "Finance").HasKey(c=>c.AccountTypeId);
entity.Property(c => c.AccountTypeId).ValueGeneratedOnAdd();
entity.Property(t => t.AccountTypeId).HasColumnName("AccountTypeId");
entity.Property(t => t.Name).HasColumnName("Name");
entity.Property(t => t.AccountTypeParentId).HasColumnName("AccountTypeParentId");
entity.HasOne(t => t.ParentType)
.WithMany()
.HasForeignKey("AccountTypeParentId");
});
modelBuilder.Entity<Account>(entity =>
{
entity.ToTable("Account", schema: "Finance");
entity.Property(c => c.AccountId).ValueGeneratedOnAdd();
entity.Property(o => o.CurrentBalance).HasColumnType("decimal(13,4)");
entity.Property(o => o.AvailableBalance).HasColumnType("decimal(13,4)");
entity.HasOne(b => b.Type).WithOne().HasForeignKey<AccountType>(b => b.AccountTypeId);
});
When trying to insert a record using the following call
Account account = CreateAccount();
AccountType type = AccountType.CreateAccountType("ParentType");
type.SetParent(AccountType.CreateAccountType("ChildType"));
account.SetType(type);
_context.Accounts.Add(account);
I am getting the following exception
SqlException: Cannot insert explicit value for identity column in table 'AccountType' when IDENTITY_INSERT is set to OFF.
It seems like everything is set right, I am new to EF Core, so not sure how it handles recursive insert.
Thanks in advance for any help.

The INSERT statement conflicted with the FOREIGN KEY SAME TABLE constraint | ASP.NET Core & Entity Framework Core Code First

I have a table named Company
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Companies](
[Id] [uniqueidentifier] NOT NULL,
[ActiveStatus] [nvarchar](max) NULL,
[Name] [nvarchar](max) NULL,
[Address] [nvarchar](max) NULL,
[Phone1] [nvarchar](max) NULL,
[Phone2] [nvarchar](max) NULL,
[Email] [nvarchar](max) NULL,
[CompanyId] [uniqueidentifier] NOT NULL,
[IsParent] [nvarchar](max) NULL,
CONSTRAINT [PK_Companies] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[Companies] WITH CHECK ADD CONSTRAINT [FK_Companies_Companies_CompanyId] FOREIGN KEY([CompanyId])
REFERENCES [dbo].[Companies] ([Id])
GO
ALTER TABLE [dbo].[Companies] CHECK CONSTRAINT [FK_Companies_Companies_CompanyId]
GO
I made this using ASP.NET Core code first, this is my class
public class BaseClass
{
[Key]
public Guid Id { get; set; }
public string ActiveStatus { get; set; }
}
public class Company: BaseClass
{
public string Name { get; set; }
public string Address { get; set; }
public string Phone1 { get; set; }
public string Phone2 { get; set; }
public string Email { get; set; }
[ForeignKey("Company")]
public Guid CompanyId { get; set; }
public Company ParentCompany { get; set; }
public string IsParent { get; set; }
public ICollection<Company> ParentCompanies { get; set; }
public ICollection<Activity> Activities { get; set; }
public ICollection<Order> Orders { get; set; }
public ICollection<Ticket> Tickets { get; set; }
public ICollection<User> Users { get; set; }
}
I want to insert data to my table using a query
INSERT [dbo].[Companies] ([Id], [ActiveStatus], [Name], [Address], [Phone1], [Phone2], [Email], [CompanyId], [IsParent]) VALUES (N'af85a23c-3832-47c9-3efe-08d79f1b5659', N'Active', N'PT. Sari Coffee Indonesia', N'Sahid Sudirman Center 27th Floor, Jl. Jend. Sudirman No.Kav. 86, RT.10/RW.11, Karet Tengsin, Kota Jakarta Pusat, Daerah Khusus Ibukota Jakarta 10220', N'+62 21 574 6501', N'+62 21 574 5808', N'feedback#starbucks.co.id', N'00000000-0000-0000-0000-000000000000', N'1')
GO
But I got an error:
Msg 547, Level 16, State 0, Line 3 The INSERT statement conflicted
with the FOREIGN KEY SAME TABLE constraint
"FK_Companies_Companies_CompanyId". The conflict occurred in database
"CRMandOMS", table "dbo.Companies", column 'Id'. The statement has
been terminated.
Please help
You wanna add 00000000-0000-0000-0000-000000000000 as a CompanyId, so you faced with this error occurs because in your table there is no company with this Id.
In your scenario there is a possibility of having a company with no parent, so your table design is wrong. for resolving this error you have to make the CompanyId foreign key nullable.
do like below:
...
[ForeignKey("Company")]
public Guid? CompanyId { get; set; }
...
Then Add-Migration and Update-Database for changing the database. Now, you can insert a company with Null parent.
good luck

How to bulk insert rows with some columns of xml type into the database?

I'm trying to bulk insert rows into the database. Some of the columns of this table are of XML type and that's where I am facing some issues.
I tried using SqlBulkCopy to achieve this but keep on getting the error that XElement cannot be converted to a string although I'm never doing a type cast.
This is my table design:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[TasksQueue]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Type] [int] NOT NULL,
[ProcessData] [xml] NOT NULL,
[MetaData] [xml] NULL,
[SubmittedBy] [int] NULL,
[Status] [int] NOT NULL,
[ResultData] [xml] NULL,
[SubmittedDate] [datetime] NULL,
[ProcessedDate] [datetime] NULL,
[ProcessingTime] [varchar](28) NULL,
[DistrictID] [int] NULL,
[Name] [nvarchar](128) NULL,
CONSTRAINT [PK_TasksQueue] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
My code in C#:
public static void CreateBulkTasks(List<Task> BulkTasks)
{
string connectionString = ConfigurationManager.AppSettings[AppSettingsKeys.QwizdomOnlineDBConnectionString];
_obj = new object();
lock (_obj)
{
DataTable tableMember = new DataTable();
DataTable tableLicense = new DataTable();
var x = BulkTasks[0].MetaData;
tableMember.Columns.Add("Type", typeof(Int32));
tableMember.Columns.Add("ProcessData", typeof(XElement));
tableMember.Columns.Add("MetaData", typeof(XElement));
tableMember.Columns.Add("SubmittedBy", typeof(Int32));
tableMember.Columns.Add("Status", typeof(Int32));
tableMember.Columns.Add("ResultData", typeof(XElement));
tableMember.Columns.Add("SubmittedDate", typeof(DateTime));
tableMember.Columns.Add("ProcessedDate", typeof(DateTime));
tableMember.Columns.Add("ProcessingTime", typeof(string));
tableMember.Columns.Add("DistrictID", typeof(Int32));
tableMember.Columns.Add("Name", typeof(string));
foreach (var task in BulkTasks)
{
tableMember.Rows.Add(
task.Type,
task.ProcessData,
task.MetaData,
task.SubmittedBy,
task.Status,
task.ResultData,
task.SubmittedDate,
task.ProcessedDate,
task.ProcessingTime,
task.DistrictID,
task.Name
);
}
using (System.Data.SqlClient.SqlBulkCopy bulkCopyGroupMembers = new System.Data.SqlClient.SqlBulkCopy(connectionString))
{
bulkCopyGroupMembers.DestinationTableName = "[TasksQueue]";
bulkCopyGroupMembers.ColumnMappings.Add("Type", "Type");
bulkCopyGroupMembers.ColumnMappings.Add("ProcessData", "ProcessData");
bulkCopyGroupMembers.ColumnMappings.Add("MetaData", "MetaData");
bulkCopyGroupMembers.ColumnMappings.Add("SubmittedBy", "SubmittedBy");
bulkCopyGroupMembers.ColumnMappings.Add("Status", "Status");
bulkCopyGroupMembers.ColumnMappings.Add("ResultData", "ResultData");
bulkCopyGroupMembers.ColumnMappings.Add("SubmittedDate", "SubmittedDate");
bulkCopyGroupMembers.ColumnMappings.Add("ProcessedDate", "ProcessedDate");
bulkCopyGroupMembers.ColumnMappings.Add("ProcessingTime", "ProcessingTime");
bulkCopyGroupMembers.ColumnMappings.Add("DistrictID", "DistrictID");
bulkCopyGroupMembers.ColumnMappings.Add("Name", "Name");
bulkCopyGroupMembers.WriteToServer(tableMember);
}
}
public class Task
{
public int? ID { get; set; }
public TasksQueueType Type { get; set; }
public XElement ProcessData { get; set; }
public XElement MetaData { get; set; }
public int? SubmittedBy { get; set; }
public string SubmittedByName { get; set; }
public TasksQueueItemStatus Status { get; set; }
public XElement ResultData { get; set; }
public int? DistrictID { get; set; }
public DateTime SubmittedDate { get; set; }
public DateTime? ProcessedDate { get; set; }
public TimeSpan? ProcessingTime { get; set; }
public bool? HighPriority { get; set; }
public string Name { get; set; }
}
I expect the bulk data to be inserted into to table in a single go. Instead I get this error:
An exception of type 'System.InvalidCastException' occurred in System.Data.dll but was not handled in user code
Additional information: Unable to cast object of type 'System.Xml.Linq.XElement' to type 'System.String'.
I think you should use XmlDocument instead of XElement in your code. The data type for ProcessData, MetaData and ResultData should be XmlDocument.
I've managed to do this by serializing the XElement to string and setting the column to string in DataTable. I already had a model created by Linq to SQL, so I prepared a second model with string in place of XElement and bulk copied that.

Sql mapping problems

I have CustomDBContext:
public class CustomDBContext : DbContext
{
public CustomDBContext(string connectionString)
: base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
......
modelBuilder.Entity<KeyProd>().ToTable("KeyProd");
......
}
}
And Repository registration in Startup.cs:
.....
var builder = new ContainerBuilder();
builder.Register(c => RepositoryFactory.GetInstance<KeyProd, long>("ef")).As<IRepository<KeyProd, long>>().InstancePerRequest();
After injection of this repository to my service, i try to add new row to database:
_keyProductionRepository.Add(new KeyProd
{
Id = key.Id,
Comment = key.Comment,
CreatedBy = adminId,
DateCreated = DateTime.UtcNow,
KeyType = key.KeyType,
PageId = key.PageId,
Name = key.Name
});
The exception is:
Cannot insert the value NULL into column 'Id', table 'ln_resources.dbo.KeyProd'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated.
The model i try to insert have id (3). Is not null.I checked it in debug mode.
My table in SQl without autoincremented Id. This is a query of table:
CREATE TABLE [dbo].[KeyProd](
[Id] [bigint] NOT NULL,
[Name] [nvarchar](100) NULL,
[KeyType] [int] NOT NULL,
[Comment] [text] NULL,
[PageId] [int] NOT NULL,
[CreatedBy] [int] NOT NULL,
[DateCreated] [datetime] NOT NULL DEFAULT (getdate()),
[DateUpdated] [datetime] NULL DEFAULT (getdate()),
[UpdatedBy] [int] NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
ALTER TABLE [dbo].[KeyProd] WITH CHECK ADD CONSTRAINT [FK_KeyProd_Page] FOREIGN KEY([PageId])
REFERENCES [dbo].[Page] ([Id])
GO
ALTER TABLE [dbo].[KeyProd] CHECK CONSTRAINT [FK_KeyProd_Page]
GO
My KeyProd Class:
public class KeyProd
{
public long Id { get; set; }
public string Name { get; set; }
public KeyType KeyType { get; set; }
public string Comment { get; set; }
public int PageId { get; set; }
public int CreatedBy { get; set; }
public DateTime DateCreated { get; set; }
public int? UpdatedBy { get; set; }
public DateTime? DateUpdated { get; set; }
}
If i try to insert this model directly from SQL SERVER by using SQL INSERT, all works fine.
Where the problem? Why Id is Null? Why mapping not working.
You may need to annotate the key field on KeyProd to indicate that you don't want the value to be automatically generated by your context. Try adding DatabaseGeneratedOption.None to your key property.
public class KeyProd {
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long Id { get; set; }
// ... Other properties
}

ServiceStack OrmLite Join Issues

I'm having a problem with ServiceStack OrmLite for SQL Server in a Visual Studio 2013 C# project. My problem is that I'm trying to use the SqlExpression builder and it's not capturing my table schema and the generated SQL code is not correct. When I run the code, I get a System.Data.SqlClient.SqlException that says "Invalid object name 'ReportPages'."
I'm using the latest NuGet version of ServiceStack.OrmLite, which is version 4.0.24.
Let me start with the table setup. Note that I removed the foreign keys for convenience:
-- Create the report pages table.
CREATE TABLE [MicroSite].[ReportPages](
[ReportPageID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](200) NULL,
[Template] [nvarchar](50) NULL,
[AccessLevel] [int] NOT NULL,
[AssignedEmployeeId] [int] NOT NULL,
[Disabled] [bit] NOT NULL,
[Deleted] [bit] NOT NULL,
[ReportSectionID] [int] NOT NULL,
[Index] [int] NOT NULL,
[Cover] [bit] NOT NULL,
CONSTRAINT [PK_dbo.ReportSections] PRIMARY KEY CLUSTERED
(
[ReportPageID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
-- Create the report sections table.
CREATE TABLE [MicroSite].[ReportSections](
[ReportSectionID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](100) NULL,
[ReportID] [int] NOT NULL,
CONSTRAINT [PK_dbo.ReportSectionGroups] PRIMARY KEY CLUSTERED
(
[ReportSectionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
-- Create the report editables table.
CREATE TABLE [MicroSite].[Editables](
[EditableID] [int] IDENTITY(1,1) NOT NULL,
[Index] [int] NOT NULL,
[Content] [nvarchar](max) NULL,
[Styles] [nvarchar](100) NULL,
[Type] [int] NOT NULL,
[ReportPageID] [int] NOT NULL,
CONSTRAINT [PK_dbo.Editables] PRIMARY KEY CLUSTERED
(
[EditableID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
So my tables basically look like this:
Here are my POCOs:
[Alias("ReportPages")]
[Schema("MicroSite")]
public partial class MicrositeReportPage : IHasId<int>
{
[Required]
public int AccessLevel { get; set; }
[Required]
public int AssignedEmployeeId { get; set; }
[Required]
public bool Cover { get; set; }
[Required]
public bool Deleted { get; set; }
[Required]
public bool Disabled { get; set; }
[Alias("ReportPageID")]
[AutoIncrement]
[PrimaryKey]
public int Id { get; set; }
[Required]
public int Index { get; set; }
public string Name { get; set; }
[Alias("ReportSectionID")]
[Required]
public int ReportSectionId { get; set; }
public string Template { get; set; }
}
[Alias("ReportSections")]
[Schema("MicroSite")]
public class MicrositeReportSection : IHasId<int>
{
[Alias("ReportSectionID")]
[AutoIncrement]
[PrimaryKey]
public int Id { get; set; }
public string Name { get; set; }
[Alias("ReportID")]
[Required]
public int ReportId { get; set; }
}
[Alias("Editables")]
[Schema("MicroSite")]
public partial class MicrositeEditable : IHasId<int>
{
public string Content { get; set; }
[Alias("EditableID")]
[AutoIncrement]
[PrimaryKey]
public int Id { get; set; }
[Required]
public int Index { get; set; }
[Alias("ReportPageID")]
[Required]
public int ReportPageId { get; set; }
public string Styles { get; set; }
[Alias("Type")]
[Required]
public int TypeId { get; set; }
}
The actual SQL statement I want to generate is this:
SELECT e.EditableID
, e.[Index]
, e.Content
, e.Styles
, e.Type
, e.ReportPageID
FROM
MicroSite.ReportSections AS rs
LEFT JOIN
MicroSite.ReportPages AS rp ON rp.ReportSectionID = rs.ReportSectionID AND rp.[Index] = 24
LEFT JOIN
MicroSite.Editables AS e ON e.ReportPageID = rp.ReportPageID
WHERE
rs.ReportID = 15
Here is my C# code:
var query = db.From<MicrositeReportSection>()
.LeftJoin<MicrositeReportSection, MicrositeReportPage>((section, page) => section.Id == page.ReportSectionId)
.LeftJoin<MicrositeReportPage, MicrositeEditable>((page, editable) => page.Id == editable.ReportPageId && page.Index == 24)
.Where<MicrositeReportSection>(section => section.ReportId == 15);
var sql = query.ToSelectStatement();
var result = db.Select<MicrositeEditable>(query)
The generated SQL statement from the sql variable looks like this (I formatted it for readability):
SELECT
"ReportSectionID",
"Name",
"ReportID"
FROM
"MicroSite"."ReportSections"
LEFT JOIN
"ReportPages" ON ("ReportSections"."ReportSectionID" = "ReportPages"."ReportSectionID")
LEFT JOIN "Editables"
ON (("ReportPages"."ReportPageID" = "Editables"."ReportPageID") AND ("ReportPages"."Index" = 24))
WHERE
("ReportSections"."ReportID" = 15)
First, the left joins are missing the schema name, which makes the SQL statement incorrect. Second, what's going on in the select statement? Those aren't the columns from the MicrositeEditable table. Am I doing this correctly or is this an actual bug with OrmLite?
I submitted a ticket with the development team and this is now fixed in version 4.0.25.

Categories

Resources