LINQ2SQL Any(), NOT EXISTS Problems - c#

I have a problem with my linq2sql while grabbing rows from database by condition select n rows from table1 where table2 doesn't contain any rows by condition table1.id != table2.accId and table1.action != "action_constant" i have such a code in my c#:
query = (from accsArray in db.Accs
where accsArray.Valid == 1 &&
!String.IsNullOrEmpty(accsArray.Password) &&
accsArray.vip_rec == 0 || accsArray.data_col == null &&
!db.Reaktors.Any(rk => rk.Action == action &&
rk.Account_id == accsArray.id)
select new DbAcc
{
id = accsArray.id,
Login = accsArray.Login,
Password = accsArray.Password,
System = accsArray.System,
//FriendsCount = Convert.ToInt32(accsArray.Friends_count)
}).Take(count).OrderBy(acc => acc.id);
!db.Reaktors.Any(rk => rk.Action == action && rk.Account_id == accsArray.id) this doesn't work, while looking for my clean sql code i see this:
SELECT [t2].[id], [t2].[Login], [t2].[System], [t2].[Password]
FROM (SELECT TOP (50) [t0].[id], [t0].[Login], [t0].[System], [t0].[Password]
FROM [Collider].[dbo].[Accs] AS [t0]
WHERE (([t0].[Valid] = 1)
AND ([t0].[Password] <> '')
AND ([t0].[Login] <> '')
AND ([t0].[data_col] = 0))
OR (([t0].[data_col] IS NULL)
AND (NOT (EXISTS(SELECT NULL AS [EMPTY]
FROM [dbo].[Reaktor] AS [t1]
WHERE [t1].[Actionself] = '_take_acc_dc'
AND ([t1].[Account_id] = [t0].[id])))))) AS [t2]
ORDER BY [t2].[id]
I'm afraid of SELECT NULL AS [EMPTY] FROM [dbo].[Reaktor] especially of NULL AS [EMPTY] so i think that's why it doesn't work correctly.

The solution is to place paranthesis right and to order conditions. The good working code will look like this:
query = (from accsArray in db.Accs
where !db.Reaktors.Any(rk => (rk.Actionself == action
&& rk.Account_id == accsArray.id))
&& accsArray.Valid == 1
&& accsArray.Password != String.Empty
&& accsArray.Login != String.Empty
&& accsArray.data_col == 0
select new DbAcc
{
id = accsArray.id,
Login = accsArray.Login,
Password = accsArray.Password,
System = accsArray.System,
}).Take(count).OrderBy(acc => acc.id);

Related

How to create Linq Query between a dataTable and a Sql Table

I have a DataTable and a SQLTable . I want to write a linq Qurty to create a result that has Information from both tables. I wrote this code. but it runs very slowly. How can I optimize it?
var Result = (from DataRow row in dTable.Rows
from obj in db.SQLTable
where (
obj.Status != "Suspend" &&
(
(obj.Type.ToLower() == "a" && obj.Code ==
row[2].ToString()) ||
(obj.Type.ToLower() == "b" &&
obj.Code.Substring(6) == row[2].ToString())
)
select new
{
ID = obj.ID,
RowNum = row[0],
}).ToList();
I'm not sure if this is 100% the correct syntax.
The idea here is that we select calculated columns to join against. That way we're calculating the obj.Type.ToLower() and obj.Code.Substring(6) once per row (n times), rather than once per join instance (n*m times).
var Result = (from DataRow row in dTable.Rows
from obj in (db.SQLTable).Select(x => new {x.Status, ObjTypeLower = x.Type.ToLower(), x.Code, ObjCodeSub = x.Code.Substring(6)})
where (
obj.Status != "Suspend" &&
(
(obj.ObjTypeLower == "a" && obj.Code ==
row[2].ToString()) ||
(obj.ObjTypeLower == "b" &&
obj.ObjCodeSub == row[2].ToString())
)
select new
{
ID = obj.ID,
RowNum = row[0],
}).ToList();
try something like this
var result=(from e in db.Users
select e.UserID).Except(from m in db.Fi
select m.UserID).ToList();

assistance required to convert SQL into LINQ

i am trying to convert the following SQL into LINQ and need some assistance with the nested select clauses for the paid_amount and paid_vat and also for the select within the where clause. Ignore the index things.
here is the SQL
SELECT
tramps.gl_transaction.debtor_uri,
tramps.debtor.account_no,
tramps.gl_transaction.uri as transaction_uri,
tramps.gl_transaction.base_currency_amount,
tramps.gl_transaction.base_currency_vat_amount,
(select IsNull(sum(gltr.base_currency_amount), 0.00)
from tramps.gl_transaction gltr
where gltr.sibling_uri = tramps.gl_transaction.uri) * (-1) as Paid_Amount ,
(select IsNull(sum(gltr.base_currency_vat_amount), 0.00)
from tramps.gl_transaction gltr
where gltr.sibling_uri = tramps.gl_transaction.uri) * (-1) as Paid_Vat ,
tramps.account.property_ref,
tramps.account.sub_ledger_code,
tramps.gl_transaction.transaction_type_code,
tramps.gl_transaction.transaction_description,
tramps.gl_transaction.effective_date
FROM tramps.account, tramps.chart WITH (INDEX (PK_CHART)), tramps.gl_transaction WITH (INDEX (glt_debtor_gen)) ,tramps.debtor, tramps.receivables_register , tramps.bank_account
WHERE tramps.chart.code = tramps.account.chart_code
AND tramps.gl_transaction.debtor_uri = tramps.debtor.uri
AND tramps.gl_transaction.account_uri = tramps.account.uri
AND tramps.receivables_register.uri = tramps.gl_transaction.receivables_register_uri
AND tramps.receivables_register.bank_account_uri = tramps.bank_account.uri
AND tramps.chart.control_account = 'Debtor'
AND tramps.gl_transaction.status = 'L'
AND tramps.gl_transaction.process_status = 'Released'
AND ( (tramps.gl_transaction.generated = 'C' AND tramps.gl_transaction.sibling_uri IS NULL AND tramps.gl_transaction.written_off <> 'Y')
OR (tramps.gl_transaction.generated = 'N' AND tramps.gl_transaction.sibling_uri IS NULL) )
AND (tramps.gl_transaction.base_currency_amount +
(select IsNull(sum(gltr.base_currency_amount), 0.00)
from tramps.gl_transaction gltr
where gltr.sibling_uri = tramps.gl_transaction.uri) <> 0.00 )
this is the LINQ i have managed to create so far, but i am struggling with the nested selects, the sum and the where clause
from acc in Accounts
join chart in Charts on acc.Chart_code equals chart.Code
join gltrans in Gl_transactions on acc.Uri equals gltrans.Account_uri
join debt in Debtors on gltrans.Debtor_uri equals debt.Uri
join recreg in Receivables_registers on gltrans.Receivables_register_uri equals recreg.Uri
join bankacc in Bank_accounts on recreg.Bank_account_uri equals bankacc.Uri
let paidcurrency = from gltrns in Gl_transactions
where gltrns.Sibling_uri == gltrans.Uri
select gltrns.Base_currency_amount
where
chart.Control_account == "Debtor"
&& gltrans.Status == "L"
&& gltrans.Process_status == "Released"
&& acc.Property_ref == 102979
&& ((gltrans.Generated == "C" && gltrans.Sibling_uri == null && gltrans.Written_off != "Y")
|| (gltrans.Generated == "N" && gltrans.Sibling_uri == null) )
select new
{
gltrans.Debtor_uri,
debt.Account_no,
gltrans.Uri,
gltrans.Base_currency_amount,
gltrans.Base_currency_vat_amount,
er = (decimal?)paidcurrency.Base_currency_vat_amount.Sum() ?? 0,
acc.Property_ref,
acc.Sub_ledger_code,
gltrans.Transaction_type_code,
gltrans.Transaction_description,
gltrans.Effective_date
}
This might help out a little. I blended in some fluent syntax to help translate the Sum functions. Let me know if some of these translations help as I can't check it directly without your schema and some data.
var result =
from acc in Accounts
join chart in Charts on acc.Chart_code equals chart.Code
join gltrans in Gl_transactions on acc.Uri equals gltrans.Account_uri
join debt in Debtors on gltrans.Debtor_uri equals debt.Uri
join recreg in Receivables_registers on gltrans.Receivables_register_uri equals recreg.Uri
join bankacc in Bank_accounts on recreg.Bank_account_uri equals bankacc.Uri
// query expression
//let paidcurrency = from gltrns in Gl_transactions
// where gltrns.Sibling_uri == gltrans.Uri
// select gltrns.Base_currency_amount
// change to fluent..
let paid_Amount = gltrans.Where(g => g.Sibling_uri == g.Uri)
.Select(g => g.Base_currency_amount * -1 ?? 0.00M).Sum()
// same for Vat..
let paid_Vat = gltrans.Where(g => g.Sibling_uri == g.Uri)
.Select(g => g.Base_currency_vat_amount * -1 ?? 0.00M).Sum()
// added another 'let' to use in the where clause..
let base_Currency = gltrans.Where(g => g.Sibling_uri == g.Uri)
.Select(g => g.Base_currenct_amount ?? 0.00M).Sum()
where
chart.Control_account == "Debtor"
&& gltrans.Status == "L"
&& gltrans.Process_status == "Released"
&& acc.Property_ref == 102979
&& (
(
gltrans.Generated == "C" &&
gltrans.Sibling_uri == null &&
gltrans.Written_off != "Y"
)
||
(
gltrans.Generated == "N" &&
gltrans.Sibling_uri == null
)
)
&& gltrans.Base_currency_amount + base_Currency != 0.00M
select new
{
gltrans.Debtor_uri,
debt.Account_no,
gltrans.Uri,
gltrans.Base_currency_amount,
gltrans.Base_currency_vat_amount,
//er = (decimal?)paidcurrency.Base_currency_vat_amount.Sum() ?? 0,
paid_Amount,
paid_Vat,
acc.Property_ref,
acc.Sub_ledger_code,
gltrans.Transaction_type_code,
gltrans.Transaction_description,
gltrans.Effective_date
};

How do I get my LINQ Query to generate the SQL statement I expect?

I have a simple web forms in which I have 3 texboxes and a dropdownlist with a search button.
This is my code to filter the EF(4.0) context based on the input chosen out of the 4 controls:
string mFormId = ddlTransValueSearchFormId.SelectedItem.Text.ToString().Trim();
string mControlId = ddlTransValueSearchControlId.SelectedItem.Text.ToString().Trim();
int mTransCategoryId;
try
{
mTransCategoryId = Int32.Parse(ddlTransValueSearchCategoryId.SelectedItem.Value.ToString());
}
catch(Exception ex)
{
throw ex;
}
string mDefaultTransValue = tbTransValueSearchDefaultValue.Text.ToString().Trim();
My LINQ Query
TranslationEntity efSchema = new TranslationEntity();
gvTransValues.DataSource = (from defaultValue in efSchema.TRANS_VALUES
.Include("TRANS_CATEGORY")
where (
mFormId == "" ? 1 == 1 : defaultValue.FormId.Contains(mFormId)
&& mControlId == "" ? 1 == 1 : defaultValue.ControlId.Contains(mControlId)
&& mTransCategoryId == -1 ? 1 == 1 : defaultValue.TransCategoryId == mTransCategoryId
&& mDefaultTransValue == "" ? 1 == 1 : defaultValue.DefaultTranValue.Contains(mDefaultTransValue)
)
select new
{
TranValueId = defaultValue.TranValueId,
FormId = defaultValue.FormId,
ControlId = defaultValue.ControlId,
TransCategoryId = defaultValue.TransCategoryId,
CategoryName = defaultValue.TRANS_CATEGORY.CategoryName,
DefaultTranValue = defaultValue.DefaultTranValue,
});
gvTransValues.DataBind();
The SQL statement that is generated
Using the profiler, this is the generated SQL query:
declare #p__linq__0 nvarchar(4000),#p__linq__1 nvarchar(4000),#p__linq__2 nvarchar(4000),#p__linq__3 nvarchar(4000),#p__linq__4 int,#p__linq__5 int,#p__linq__6 nvarchar(4000),#p__linq__7 nvarchar(4000)
SELECT #p__linq__0=N'',#p__linq__1=N'%%',#p__linq__2=N'',#p__linq__3=N'%%',#p__linq__4=1,#p__linq__5=1,#p__linq__6=N'cat',#p__linq__7=N'%cat%'
SELECT
[Extent1].[TRAN_VALUE_ID] AS [TRAN_VALUE_ID],
[Extent1].[FORM_ID] AS [FORM_ID],
[Extent1].[CONTROL_ID] AS [CONTROL_ID],
[Extent1].[TRANS_CATEGORY_ID] AS [TRANS_CATEGORY_ID],
[Extent2].[CATEGORY_NAME] AS [CATEGORY_NAME],
[Extent1].[DEFAULT_TRAN_VALUE] AS [DEFAULT_TRAN_VALUE]
FROM [dbo].[TRANS_VALUES] AS [Extent1]
LEFT OUTER JOIN [dbo].[TRANS_CATEGORY] AS [Extent2] ON [Extent1].[TRANS_CATEGORY_ID] = [Extent2].[TRANS_CATEGORY_ID]
WHERE
(CASE
WHEN (N'' = #p__linq__0) THEN cast(1 as bit)
WHEN (([Extent1].[FORM_ID] LIKE #p__linq__1 ESCAPE N'~') AND (N'' = #p__linq__2)) THEN cast(1 as bit)
WHEN (([Extent1].[CONTROL_ID] LIKE #p__linq__3 ESCAPE N'~') AND (-1 = #p__linq__4)) THEN cast(1 as bit)
WHEN (([Extent1].[TRANS_CATEGORY_ID] = #p__linq__5) AND (N'' = #p__linq__6)) THEN cast(1 as bit)
WHEN ([Extent1].[DEFAULT_TRAN_VALUE] LIKE #p__linq__7 ESCAPE N'~') THEN cast(1 as bit)
WHEN ( NOT ([Extent1].[DEFAULT_TRAN_VALUE] LIKE #p__linq__7 ESCAPE N'~')) THEN cast(0 as bit)
END) = 1
Which is not what I want. Regardless of the parameters values, the way the script is generated by EF, is returning ALL rows from the database.
What is going wrong here?
The SQL statement I want
In fact, what I would need and consider to be optimal in terms of SQL server would be to get EF to generate this kind of query.
SELECT
[Extent1].[TRAN_VALUE_ID] AS [TRAN_VALUE_ID],
[Extent1].[FORM_ID] AS [FORM_ID],
[Extent1].[CONTROL_ID] AS [CONTROL_ID],
[Extent1].[TRANS_CATEGORY_ID] AS [TRANS_CATEGORY_ID],
[Extent2].[CATEGORY_NAME] AS [CATEGORY_NAME],
[Extent1].[DEFAULT_TRAN_VALUE] AS [DEFAULT_TRAN_VALUE]
FROM [dbo].[TRANS_VALUES] AS [Extent1]
LEFT OUTER JOIN [dbo].[TRANS_CATEGORY] AS [Extent2] ON [Extent1].[TRANS_CATEGORY_ID] = [Extent2].[TRANS_CATEGORY_ID]
WHERE
ISNULL([Extent1].[FORM_ID],N'') LIKE '%' + COALESCE(#p__linq__0,[Extent1].[FORM_ID],N'') + '%'
AND ISNULL([Extent1].[CONTROL_ID],N'') LIKE '%' + COALESCE(#p__linq__1,[Extent1].[CONTROL_ID],N'') + '%'
AND ISNULL([Extent1].[TRANS_CATEGORY_ID],-1) = COALESCE(#p__linq__2,[Extent1].[TRANS_CATEGORY_ID],-1)
AND ISNULL([Extent1].[DEFAULT_TRAN_VALUE],N'') LIKE '%' + COALESCE(#p__linq__3,[Extent1].[DEFAULT_TRAN_VALUE],N'') + '%'
go
Try writing it this way:
(from defaultValue in efSchema.TRANS_VALUES
.Include("TRANS_CATEGORY")
where (defaultValue.FormId.Contains(mFormId) || mFormId == "")
&& (defaultValue.ControlId.Contains(mControlId) || mControlId == "")
&& (defaultValue.TransCategoryId.Contains(mTransCategoryId) || mTransCategoryId == "")
&& (defaultValue.DefaultTranValue.Contains(mDefaultTransValue) || mDefaultTransValue == ""))
This would be a lot simpler if you constructed your query in small steps.
var query = efSchema.TRANS_VALUES.Include("TRANS_CATEGORY");
if(!string.IsNullOrEmpty(mFormId))
{
query = query.Where(defaultValue => defaultValue.FormId.Contains(mFormId));
}
if(!string.IsNullOrEmpty(mControlId))
{
query = query.Where(defaultValue => defaultValue.ControlId.Contains(mControlId));
}
if(mTransCategoryId != -1)
{
query = query.Where(defaultValue => defaultValue.TransCategoryId == mTransCategoryId);
}
if(!string.IsNullOrEmpty(mDefaultTransValue))
{
query = query.Where(defaultValue => defaultValue.DefaultTransValue.Contains(mDefaultTransValue));
}
gvTransValues.DataSource = query.Select(defaultValue => new
{
TranValueId = defaultValue.TranValueId,
FormId = defaultValue.FormId,
ControlId = defaultValue.ControlId,
TransCategoryId = defaultValue.TransCategoryId,
CategoryName = defaultValue.TRANS_CATEGORY.CategoryName,
DefaultTranValue = defaultValue.DefaultTranValue,
});
(I think it should work like this but you might have to specify the initial type of query to IQueryable<YOURTYPE>)

linq nested select in Contains method

Can this be converted to a single LINQ statement?
SELECT COUNT(*)
FROM Abstract_Dedications_Lookup
WHERE PlatEntryNumber = 10383772
AND CommonArea = 0
AND ((OuterType <> '' AND OuterValue <> '') OR (InnerType <> '' AND InnerValue <> ''))
AND ParcelNumber IN
(SELECT ParentParcelNumber
FROM Parcel_Title_History
WHERE EntryNumber <> 10383772
AND ParentParcelNumber <> '0'
AND ChildParcelNumber <> ParentParcelNumber)
I have tried many variations and can not get the correct syntax in the ".Contains" method. Can a "SELECT" be used within the "Contains"?
var query2 = from d in context.RTV_ParcelDedicationLocations
from p in context.RTV_ParcelTitleHistory
where d.PlatEntryNumber == PlatEntryNum
where d.CommonArea == false
where (d.OuterType != "" && d.OuterValue != "") || (d.InnerType != "" && d.InnerValue != "")
where d.ParcelNumber.Contains(p.ChildParcelNumber != p.ParentParcelNumber)
select d;
var results2 = query2.ToList();
You can create separate linq statements that will get executed by the database as 1 query. A linq statement dosent actually get execute until you begin to iterate over it.
The way I thought about this problem was to define a query that gets valid ParentParcelNumber from Parcel_Title_History. Then create another query that checks if the items in Abstract_Dedications_Lookup are in the first query. Try something like this:
var query1 = from p in context.RTV_ParcelTitleHistory
where p.EntryNumber != 10383772 & p.ParentParcelNumber != "0" & p.ChildParcelNumber != p.ParentParcelNumber
select p.ParentParcelNumber;
var query2 = from d in context.RTV_ParcelDedicationLocations
where d.PlatEntryNumber == 10383772
& d.CommonArea == 0
& ((d.OuterType != "" && d.OuterValue != "") || (d.InnerType != "" && d.InnerValue != ""))
& query1.Contains(d.ParcelNumber)
select d;
var results2 = query2.ToList();
The LINQ generated SQL statement below returns 44,092 records but should be same as the SQL in the OP which returns 182 records. Something in the query2 LINQ isn't correct apparently:
SELECT
[Extent1].[ParcelNumber] AS [ParcelNumber],
[Extent1].[PlatEntryNumber] AS [PlatEntryNumber],
[Extent1].[OuterType] AS [OuterType],
[Extent1].[OuterValue] AS [OuterValue],
[Extent1].[InnerType] AS [InnerType],
[Extent1].[InnerValue] AS [InnerValue],
[Extent1].[CommonArea] AS [CommonArea]
FROM (SELECT
[RTV_ParcelDedicationLocations].[ParcelNumber] AS [ParcelNumber],
[RTV_ParcelDedicationLocations].[PlatEntryNumber] AS [PlatEntryNumber],
[RTV_ParcelDedicationLocations].[OuterType] AS [OuterType],
[RTV_ParcelDedicationLocations].[OuterValue] AS [OuterValue],
[RTV_ParcelDedicationLocations].[InnerType] AS [InnerType],
[RTV_ParcelDedicationLocations].[InnerValue] AS [InnerValue],
[RTV_ParcelDedicationLocations].[CommonArea] AS [CommonArea]
FROM [dbo].[RTV_ParcelDedicationLocations] AS [RTV_ParcelDedicationLocations]) AS [Extent1]
WHERE (([Extent1].[PlatEntryNumber] = 10383772) AND (10383772 IS NOT NULL)
AND (0 = [Extent1].[CommonArea]) AND ('''' <> [Extent1].[OuterType]) AND ('''' <> [Extent1].[OuterValue]))
OR (('''' <> [Extent1].[InnerType]) AND ('''' <> [Extent1].[InnerValue])
AND ( EXISTS (SELECT 1 AS [C1]
FROM (SELECT [RTV_ParcelTitleHistory].[EntryNumber] AS [EntryNumber],
[RTV_ParcelTitleHistory].[ParentParcelNumber] AS [ParentParcelNumber],
[RTV_ParcelTitleHistory].[ChildParcelNumber] AS [ChildParcelNumber],
[RTV_ParcelTitleHistory].[Book] AS [Book],
[RTV_ParcelTitleHistory].[Page] AS [Page]
FROM [dbo].[RTV_ParcelTitleHistory] AS [RTV_ParcelTitleHistory]) AS [Extent2]
WHERE ( NOT (([Extent2].[EntryNumber] = 10383772) AND (10383772 IS NOT NULL))) AND ('0' <> [Extent2].[ParentParcelNumber]) AND ([Extent2].[ChildParcelNumber] <> [Extent2].[ParentParcelNumber]) AND ([Extent2].[ParentParcelNumber] = [Extent1].[ParcelNumber])
)))

Entity Framework - can't make LEFT OUTER join to work

See below 2 versions of code and SQL it produces. I want to load preferences but I also want to bring only my user preferences and therefore I use WHERE clause. But as soon as I put it in - I don't get OUTER join anymore. Why?
var query = from p in context.Preferences
join up in context.UserPreferences on p.PreferenceKey equals up.PreferenceKey into outer
from up in outer.DefaultIfEmpty()
select new MobileRESTEntities.UserPreference
{
CreatedOn = (up == null) ? p.CreatedOn : up.CreatedOn,
UpdatedOn = (up == null) ? p.CreatedOn : (up.UpdatedOn ?? up.CreatedOn),
PreferenceId = p.PreferenceId,
Value = (up == null) ? p.ValueDefault : up.Value,
};
With WHERE:
var query = from p in context.Preferences
join up in context.UserPreferences on p.PreferenceKey equals up.PreferenceKey into outer
from up in outer.DefaultIfEmpty()
where up.UserKey.Equals((int)user.ProviderUserKey)
&&
(
(up == null)
||
((up.UpdatedOn > lastSyncOn && up.UpdatedOn != null) || (up.CreatedOn > lastSyncOn))
)
select new MobileRESTEntities.UserPreference
{
CreatedOn = (up == null) ? p.CreatedOn : up.CreatedOn,
UpdatedOn = (up == null) ? p.CreatedOn : (up.UpdatedOn ?? up.CreatedOn),
PreferenceId = p.PreferenceId,
Value = (up == null) ? p.ValueDefault : up.Value,
};
Without WHERE - GOOD
SELECT
[Extent1].[PreferenceKey] AS [PreferenceKey],
CASE WHEN ([Extent2].[UserPreferenceKey] IS NULL) THEN [Extent1].[CreatedOn] ELSE [Extent2].[CreatedOn] END AS [C1],
CASE WHEN ([Extent2].[UserPreferenceKey] IS NULL) THEN [Extent1].[CreatedOn] WHEN ([Extent2].[UpdatedOn] IS NULL) THEN [Extent2].[CreatedOn] ELSE [Extent2].[UpdatedOn] END AS [C2],
[Extent1].[PreferenceId] AS [PreferenceId],
CASE WHEN ([Extent2].[UserPreferenceKey] IS NULL) THEN [Extent1].[ValueDefault] ELSE [Extent2].[Value] END AS [C3]
FROM [dbo].[MBLPreference] AS [Extent1]
LEFT OUTER JOIN [dbo].[MBLUserPreference] AS [Extent2] ON [Extent1].[PreferenceKey] = [Extent2].[PreferenceKey]
With WHERE - BAD - no OUTER JOIN
exec sp_executesql N'SELECT
[Extent1].[PreferenceKey] AS [PreferenceKey],
[Extent2].[CreatedOn] AS [CreatedOn],
CASE WHEN ([Extent2].[UpdatedOn] IS NULL) THEN [Extent2].[CreatedOn] ELSE [Extent2].[UpdatedOn] END AS [C1],
[Extent1].[PreferenceId] AS [PreferenceId],
[Extent2].[Value] AS [Value]
FROM [dbo].[MBLPreference] AS [Extent1]
INNER JOIN [dbo].[MBLUserPreference] AS [Extent2] ON [Extent1].[PreferenceKey] = [Extent2].[PreferenceKey]
WHERE ([Extent2].[UserKey] = #p__linq__0) AND ((1 = 0) OR (([Extent2].[UpdatedOn] > #p__linq__1) AND ([Extent2].[UpdatedOn] IS NOT NULL)) OR ([Extent2].[CreatedOn] > #p__linq__2))',N'#p__linq__0 int,#p__linq__1 datetime2(7),#p__linq__2 datetime2(7)',#p__linq__0=15,#p__linq__1='0001-01-01 00:00:00',#p__linq__2='0001-01-01 00:00:00'
EDIT
Well yes, WHERE Won't work as is but my SQL should looks something like:
SELECT P.*
FROM dbo.MBLPreference P
LEFT OUTER JOIN dbo.MBLUserPreference UP ON P.PreferenceKey = UP.PreferenceKey
AND UP.UserKey = 8 AND UP.CreatedOn > '1-1-1'
How should I write LINQ to achieve this?
ANSWER
This is what I needed to do (Move conditions onto join itself)
var query = from p in context.Preferences
join up in context.UserPreferences
.Where(x =>
x.UserKey.Equals((int)user.ProviderUserKey)
&&
((x.UpdatedOn > lastSyncOn && x.UpdatedOn != null) || (x.CreatedOn > lastSyncOn))
)
on p.PreferenceKey equals up.PreferenceKey into outer
from up in outer.DefaultIfEmpty()
select new MobileRESTEntities.UserPreference
{
CreatedOn = (up == null) ? p.CreatedOn : up.CreatedOn,
UpdatedOn = (up == null) ? p.CreatedOn : (up.UpdatedOn ?? up.CreatedOn),
PreferenceId = p.PreferenceId,
Value = (up == null) ? p.ValueDefault : up.Value,
};
I'm not sure what you are trying to achieve, but I believe you need to move condition in where up :
from p in context.Preferences
join up in context.UserPreferences.Where(x=>x.UserKey ==user.ProviderUserKey &&
(// your other conditions)
)
into outer ....

Categories