EF DefaultIfEmpty where statement - c#

I have three tables and I am trying to get the Customer Response. This Customer has not Answer the question so in the MeetingPollingResponseValues CustomerId is null as well as MeetingPollingPartsValuesId. But I need to have that where (mppss.MeetingPollingPartsId == MeetingPollingPartsId && mppvs.CustomerId == CustomerId) for when Customer has data in that table. I have a the DefaultIfEmpty so I not sure if I need to add or to the where statement?
DB Tables
CREATE TABLE [dbo].[MeetingPollingParts](
[MeetingPollingPartsId] [int] IDENTITY(1,1) NOT NULL,
[MeetingPollingQuestionId] [int] NULL,
[MeetingPollingPartsTypeId] [int] NULL
)
CREATE TABLE [dbo].[MeetingPollingPartsValues](
[MeetingPollingPartsValuesId] [int] IDENTITY(1,1) NOT NULL,
[QuestionValue] [nvarchar](max) NULL,
[MeetingPollingPartsValuesTypeId] [int] NULL,
[MeetingPollingPartsId] [int] NULL
)
CREATE TABLE [dbo].[MeetingPollingResponseValues](
[MeetingPollingResponseValuesId] [int] IDENTITY(1,1) NOT NULL,
[MeetingPollingPartsValuesId] [int] NULL,
[CustomerId] [int] NULL
)
DB
QuestionValue| MeetingPollingPartsId| MeetingPollingPartsValuesId| CustomerId
--------------------------------------------------------------------------------
Yes | 588 | NULL | NULL
No | 588 | NULL | NULL
EF
var MeetingPollingParticipantsAnswers = (from mppss in db.MeetingPollingParts
join mppv in db.MeetingPollingPartsValues on mppss.MeetingPollingPartsId equals mppv.MeetingPollingPartsId
join mppvs in db.MeetingPollingResponseValues on mppv.MeetingPollingPartsValuesId equals mppvs.MeetingPollingPartsValuesId into actualAnswers
from mppvs in actualAnswers.DefaultIfEmpty()
where (mppss.MeetingPollingPartsId == MeetingPollingPartsId && mppvs.CustomerId == CustomerId)
select new Model.MeetingPollingParticipantsAnswers
{
Question = mppv.QuestionValue,
Selected = aa.MeetingPollingPartsValuesId == aa.MeetingPollingPartsValuesId ? true : false,
MeetingPollingPartsValuesId = aa.MeetingPollingPartsValuesId
}).ToList();

Related

Unable to fetch data using SQL Server datalength function due to performance issues

I have a documents table in my database. The document table structure is like
CREATE TABLE [dbo].[Documents]
(
[DocumentId] [BIGINT] NOT NULL IDENTITY(1, 1),
[ObjectType] [VARCHAR](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[ObjectId] [BIGINT] NOT NULL,
[DocumentName] [VARCHAR](250) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[DocumentFile] [VARBINARY](MAX) NOT NULL,
[isTemp] [BIT] NOT NULL CONSTRAINT [DF_Documents_isTemp] DEFAULT ((0)),
[IsActive] [BIT] NOT NULL,
[RowGuid] [UNIQUEIDENTIFIER] NOT NULL CONSTRAINT [DF_Documents_RowGuid] DEFAULT (newid()),
[CreatedBy] [BIGINT] NOT NULL,
[CreatedOn] [DATETIME] NOT NULL,
[UpdatedBy] [BIGINT] NULL,
[UpdatedOn] [DATETIME] NULL
)
GO
-- Constraints and Indexes
ALTER TABLE [dbo].[Documents]
ADD CONSTRAINT [PK_Documents]
PRIMARY KEY CLUSTERED ([DocumentId])
GO
CREATE NONCLUSTERED INDEX [ix_DocumentName]
ON [dbo].[Documents] ([DocumentName])
GO
CREATE NONCLUSTERED INDEX [ix_ObjectId]
ON [dbo].[Documents] ([ObjectId])
GO
CREATE NONCLUSTERED INDEX [ix_ObjectType]
ON [dbo].[Documents] ([ObjectType])
GO
In the documents table there are 100k records.
This is the C# method which is fetching single document on the basis of objectid.
public IQueryable<Document> GetDocumentData(long objectId, string objectType)
{
var searchResults = new MerrickEntities().Documents.Where(c => c.ObjectId == objectId && c.ObjectType == objectType && SqlFunctions.DataLength(c.DocumentFile) > 0);
return searchResults.AsQueryable();
}
In this query is not fetching data and it seems the issue is caused by datalength function.
How can I optimize this query?

Dynamic selecting of children records

I have a table for comments where I can add records in n levels, it means that I can have a comment that it is in the nth level of reply of a comment.
My problem is that how can I dynamically select n levels of comment using linq?
For example I want comments reply for 5th level or 2nd or nth.
Here is my table
public partial class {
public Comment()
{
this.Comments1 = new HashSet<Comment>();
}
public int CommentId { get; set; }
public Nullable<int> ParentId { get; set; }
public string Title { get; set; }
public virtual ICollection<Comment> Comments1 { get; set; }
public virtual Comment Comment1 { get; set; }
}
till now i use linq and call this function in sql-server to get all the children :
[DbFunction("Ents", "cmTree")]
public virtual IQueryable<ContentComment> cmTree(string topLevelComments)
{
var topLevelCommentsParameter = topLevelComments != null ?
new ObjectParameter("topLevelComments", topLevelComments) :
new ObjectParameter("topLevelComments", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<ContentComment>("[Entities].[cmTree](#topLevelComments)", topLevelCommentsParameter);
}
an then in sql-server:
ALTER FUNCTION [dbo].[cmTree]
(
-- Table types seems goods here.
-- but in application-level, linq to sql technology dose not support table types.
-- TupleValue type can user for future use.
#topLevelComments NVARCHAR(max)
)
RETURNS #resultTable TABLE (
[Id] [bigint] primary KEY NOT NULL,
[AuthorUserId] [int] NULL,
[AuthorName] [nvarchar](128) NULL,
[AuthorEmail] [nvarchar](256) NULL,
[AuthorUrl] [nvarchar](512) NULL,
[AuthorIp] [nvarchar](100) NULL,
[InsertDateTime] [datetime] NOT NULL,
[BodyContent] [nvarchar](max) NOT NULL,
[IsApproved] [bit] NOT NULL,
[IsAlertable] [bit] NOT NULL,
[ContentId] [bigint] NOT NULL,
[ParentCommentId] [bigint] NULL,
[VerifierUserID] [int] NULL,
[VerifyDateTime] [datetime] NULL,
[Status] [bit] NOT NULL,
[LastModifierUserId] [int] NULL,
[LastModifiedDateTime] [datetime] NULL
)
AS
BEGIN
with CommentTableExpression As (
-- Anchor entities
select rC.Id, rc.AuthorUserId, rc.AuthorName, rc.[AuthorEmail], rc.[AuthorUrl], rc.[AuthorIp], rc.[InsertDateTime], rc.[BodyContent], rc.[IsApproved], rc.[IsAlertable], rc.[ContentId], rc.[ParentCommentId], rc.[VerifierUserID], rc.[VerifyDateTime], rc.[Status], rc.[LastModifierUserId], rc.[LastModifiedDateTime]
from dbo.ContentComments as rC
WHERE rc.ParentCommentId IN (SELECT * FROM dbo.CSVToTable(#topLevelComments))
union all
-- Recursive query execution
select child.Id, child.AuthorUserId, child.AuthorName, child.[AuthorEmail], child.[AuthorUrl], child.[AuthorIp], child.[InsertDateTime], child.[BodyContent], child.[IsApproved], child.[IsAlertable], child.[ContentId], child.[ParentCommentId], child.[VerifierUserID], child.[VerifyDateTime], child.[Status], child.[LastModifierUserId], child.[LastModifiedDateTime]
from dbo.ContentComments as child
inner join CommentTableExpression as t_Comment
on child.ParentCommentId = t_Comment.Id
where child.ParentCommentId is not NULL) -- commente contet=nt budan barasi shavad.
INSERT #resultTable Select * from CommentTableExpression
RETURN
END
Any help would be appreciated..
It will be better to manage one more field in the table called "ChildLevel" and add reply level in that field.
But if you want to use same structure and want to manage then below linq will get 5th level children
var rec = dt.Comments().Where(t => t.Comment1 != null
&& t.Comment1.Comment1 != null
&& t.Comment1.Comment1.Comment1 != null
&& t.Comment1.Comment1.Comment1.Comment1 != null );

Adding data to database using asp.net mvc

I'm trying to add data to the Event table in SQL Server.
This is the table details:
CREATE TABLE [dbo].[Event]
(
[EventID] [int] IDENTITY(1001,1) NOT NULL,
[EventName] [nvarchar](50) NOT NULL,
[EventDesc] [nvarchar](50) NOT NULL,
[EventLogo] [image] NULL,
[EventLocation] [decimal](9, 6) NULL,
[EventDate] [nvarchar](20) NOT NULL,
[EventStartTime] [nvarchar](7) NOT NULL,
[EventEndTime] [nvarchar](7) NOT NULL,
[NumOfAttendees] [nvarchar](7) NULL,
[EventStatus] [nvarchar](5) NOT NULL,
[UserID] [int] NULL,
[CategoryID] [int] NULL,
[RatingID] [int] NULL,
[FeedbackID] [int] NULL
)
This is where I receive the error:
Keyword, identifier or string expected after verbatim specifier #
This is the EventController code:
public ActionResult Index()
{
var events = db.Events.Include(# => #.Category).Include(# => #.Feedback).Include(# => #.Rating).Include(# => #.User);
return View(events.ToList());
}
Change it to -
db.Events.Include(c => c.Category).Include(f => f.Feedback).Include(r => r.Rating).Include(u => u.User);
# is a keyword which is used for verbatim literals.

Order by child records using dynamic field with entity framework

I am interested in sorting a query using entity framework and am having trouble sorting using a dynamic order by expression,
I have a parent record (DatasetRecord) with a one to many relationship consisting of a number of associated values (DatasetValues), I would like to be able to sort based on the data stored within the value if it matches a certain field,
So I need to sort by the Value of DatasetValues where it matches a supplied FieldID
public IEnumerable<DatasetRecordDto> FetchData(ModuleSettingsDto settings)
{
var query = _context.DatasetRecords.AsQueryable().Where(r => r.DatasetId == settings.DatasetId && r.IsDeleted == false);
foreach (var filter in settings.Filters)
{
// this works fine, check we have current field and value matches
query = query.Where(i => i.DatasetValues.Any(x => x.DatasetFieldId == filter.DatasetFieldId && x.Value == filter.Value));
}
foreach (var sort in settings.Sort)
{
switch (sort.SortDirection)
{
case "asc":
// THIS IS WHERE I NEED THE DYNAMIC ORDER BY EXPRESSION,
// THIS SHOULD SORT BY DATETIME WHERE FIELD ID MATCHES
query = query.OrderBy(i => i.DatasetValues.Any(x => x.ValueDateTime && x.DatasetFieldId == sort.DatasetFieldId));
break;
}
}
return ShapeResults(query);
}
And here is my database schema:
CREATE TABLE [dbo].[DatasetRecords](
[Id] [int] IDENTITY(1,1) NOT NULL,
[DatasetId] [int] NOT NULL
)
CREATE TABLE [dbo].[DatasetFields](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Label] [varchar](50) NOT NULL,
[DatasetId] [int] NULL,
[DataType] [int] NOT NULL
)
CREATE TABLE [dbo].[DatasetValues](
[Id] [int] IDENTITY(1,1) NOT NULL,
[DatasetRecordId] [int] NOT NULL,
[DatasetFieldId] [int] NOT NULL,
[ValueString] [varchar](8000) NULL,
[ValueInt] [int] NULL,
[ValueDateTime] [datetime] NULL,
[ValueDecimal] [decimal](18, 2) NULL,
[ValueBit] [bit] NULL
)
Please let me know if you need any further info, any help is greatly appreciated,
UPDATE: I am not having an issue with creating a dynamic order by expression, I am trying to apply a conditional sort order for parent records based on the values in a child table
Have you tried running the Linq code on something like LinqPad, it lets you run Linq code against a dataset and shows you the generated SQL. You can take that SQL and run it manually to make sure it isn't some invalid SQL that is causing the error.

Monthly billing system - query to get list of defaulters who have not paid their dues by today

this is the customers table, column 'C_BillingDay' indicates on which day the bill are due monthly for example if value is 4 thn billing due date of that customer is 4rth of each month. he has to pay his dues on 4rth ..
CREATE TABLE [dbo].[Customers](
[CID] [int] IDENTITY(1,1) NOT NULL,
[C_Name] [varchar](50) NULL,
[C_EmailID] [varchar](20) NULL,
[C_MobileNo] [varchar](20) NULL,
[C_PhoneNo] [varchar](20) NULL,
[C_HomeAddress] [varchar](max) NULL,
[C_ServiceArea] [int] NULL,
[C_AccountStatus] [int] NULL,
[C_IPAdress] [varchar](50) NULL,
[C_MACAddress] [varchar](50) NULL,
[C_Package] [int] NULL,
[C_BillingDay] [int] NULL,
[Balance] [float] NULL,
[C_AccountCreated] [datetime] NULL,
[C_AccountModified] [datetime] NULL,
payments' table:
TABLE [dbo].[Payments](
[PID] [int] IDENTITY(1,1) NOT NULL,
[CID] [int] NULL,
[Amount] [int] NULL,
[PaymentType] [int] NULL,
[Details/Comments] [varchar](max) NULL,
[DateTimeRecieved] [datetime] NULL,
[DateTimeModified] [datetime] NULL,
please help me quering all the defaulters who have not paid their dues on time by today ...
i have been trying with similar functions like DATEADD(MONTH,-1,GETDATE()) but they are not giving desired results :S
select * from Customers,payments
where Payments.DateTimeRecieved
NOT BETWEEN GETDATE() AND DATEADD(MONTH,-1,GETDATE())
From the limited system information given, I suspect there would be two relevant processes.
The first a daily job which does an UPDATE on the [Balance] column for all records in [Customers] based on [C_Package] (perhaps this indicates a monthly fee stored elsewhere), [C_AccountStatus] (perhaps indicating whether they are active), [C_BillingDay], and todays date.
Once that is done all you need to do is
SELECT [CID] FROM [dbo].[Customers] WHERE [Balance] > 0
Hope this helps.
Edit ...
To select Customers who haven't made a payment (though the logic seems flawed):
SELECT c.[CID]
FROM [Customers] c
WHERE c.[CID] NOT IN
(SELECT p.[CID] FROM [Payments] p
WHERE p.[DateTimeRecieved] BETWEEN GETDATE() AND DATEADD(MONTH,-1,GETDATE()))
(There's probably a way more elegant query than that!)
What about checking if the balance is not 0 and that today is the date of their payment. Something like:
select * from customers, payments where customers.balance > 0 and todays_date >= billdate;
its a bit abstract because i dont really know what language we are dealing with or what form your dates are in.
I am also making an assumption that they pay off their entire balance when they pay their dues

Categories