Linq To SQL Method with .Contains fails - c#

I have the below Linq To SQL Method. When I step through the code spcCodeIDs contains the seven entries I am expecting. However I get a run-time exception of
Method 'Boolean Contains(System.String)' has no supported translation to SQL.
What am I missing?
public static DataTable GetSPCCodeList()
{
using (var context = ProviderDataContext.Create())
{
IQueryable<tblProviderAdminSPCCode> tSPCCode = context.GetTable<tblProviderAdminSPCCode>();
IList<string> spcCodeIDs = BLLCmo.FCApprovedSPCsForGreenSheet();
return (tSPCCode
.Where(spcCode => spcCode.Inactive == null && spcCodeIDs.Contains(spcCode.SPCCodeID))
.OrderBy(spcCode => spcCode.SPCCodeID)
.Select(spcCode => new { spcCode.SPCCodeID, spcCode.SPCDescription, spcCode.SPCCategoryID }))
.CopyLinqToDataTable();
}
}

LINQ to SQL can only support Contains translations form a concrete list and not the IList interface.. try changing your line from
IList<string> spcCodeIDs = BLLCmo.FCApprovedSPCsForGreenSheet();
to
List<string> spcCodeIDs = BLLCmo.FCApprovedSPCsForGreenSheet().ToList();

You need to pass a string as a parameter to Contains. So trying passing spcCode.SPCCodeID.ToString()

Related

How can I convert 'System.Collection.Generic.List<String>' into 'System.Windows.Documents.List'?

I have a table of doctors in my database. So I'm trying to get the list of the firstName of the doctors in my database.
In the ViewModel class I'm using this code to get it
public List DoctorsList ()
{
// string mainconn = Configuration
List ListOfDoctors;
using (var context = new GlabDbContext())
{
var result = (from c in context.Doctors
select c.LastName).ToList();
ListOfDoctors = result;
}
return ListOfDoctors;
}
I want to use this function like a method of my ViewModel class an it will have a return.
But I'm getting an error saying that:
Impossible to convert implicitely 'System.Collections.Generic.List into 'System.Windows.Documents.List'?
I try to cast the result like this
public List DoctorsList ()
{
// string mainconn = Configuration
List ListOfDoctors;
using (var context = new GlabDbContext())
{
var result = (from c in context.Doctors
select c.LastName).ToList();
**ListOfDoctors = (list)result;**
}
return ListOfDoctors;
}
but I get an error at the run time for the app.
How can I resolve the problem?
Your List ListOfDoctors appears to be really an
System.Windows.Documents.List ListOfDoctors;
and this is also the return type of your method.
Your var result really is
System.Collections.Generic.List<string> result
The two types are not compatible, meaning that you cannot cast one to the other (as the error message says).
I suspect you don't really want to return a Documents.List but a List<string> (containing just those names). So:
Remove a using System.Windows.Documents; from your file
Change all List to List<string>
You can try this like this:
System.Windows.Documents.List listx = new System.Windows.Documents.List();
foreach (var r in result)
{
listx.ListItems.Add(new ListItem(new Paragraph(new Run(r)));
}
Most probably you had an intention to use the IList or List<T>, but accidentally imported the System.Windows.Documents.List and all the later errors appeared because of that.
Please, take a moment and think what return type do you really need and if you want to return a collection of string elements then either use List<string> or IList as a return type:
public IList DoctorsList() // or return List<string> or IList<string> (generic version)
{
// string mainconn = Configuration
IList ListOfDoctors;
using (var context = new GlabDbContext())
{
var result = (from c in context.Doctors
select c.LastName).ToList();
ListOfDoctors = result;
}
return ListOfDoctors;
}
Shorter version (c# 8 compatable):
public IList DoctorsList() // or return List<string> or IList<string> (generic version)
{
using var context = new GlabDbContext();
return (from c in context.Doctors select c.LastName).ToList();
}
Remember:
You can do casting only with compatible types, which means that there should be either appropriate conversion operators defined for both types or a BaseāŸ¶Derived class relationship should exist between types.
For more information:
About Casting and type conversions read here.
About Type conversion operators read here.

EF - finding items which are not in the list of integers - resulting query doesn't use parameters

I am using the following method:
public PagedResult<PaymentPlanItems> GetPagedRequest(SearchRequest searchRequest, List<int> idsToExclude)
{
var list = _dbSetList.AsQueryable();
if (idsToExclude != null)
{
list = list.Where(item => !idsToExclude.Contains(item.ItemId));
}
var query = SearchHelper.GetFilteredSearch<PaymentPlanItems>(list, searchRequest);
var pagedResultMessage = SearchHelper.GetPagedResult(query, searchRequest);
return pagedResultMessage;
}
where idsToExclude I originally got using this (found from another SO thread):
if (!string.IsNullOrEmpty(searchViewModel.ItemsToExclude))
{
List<int> idsToExclude = new List<int>(Array.ConvertAll(searchViewModel.ItemsToExclude.Split(','), int.Parse));
searchViewModel.Result = _paymentPlanItemsAdapter.GetPagedRequest(searchViewModel.SearchRequest, idsToExclude);
}
I then look at the generated query using profile and I see that I get the following as part of my query:
WHERE ( NOT ([Extent1].[ItemId] IN (440, 1017)))
I don't know if I should be really concerned as my numbers get inserted into the query directly and not as parameters and if I should be, what modifications to this method / approach I should take to make this query use parameters?

Entity framework: Retrieving data with column name and value

If I use:
private List<string> GetDataFrom()
{
var result = new List<string>();
using (var context = new mainEntities())
{
var matches = context.data.Where(s => s.Width == 500).ToList();
result.AddRange(matches.Select(t => t.Key));
}
return result;
}
It is giving me perfect results, but I want to use a method where I can use column name and value, like this:
private List<string> GetDataFrom(string columnName, int valToMatch)
{
var result = new List<string>();
using (var context = new mainEntities())
{
var propertyInfo = typeof(data).GetProperty(columnName).Name;
var matches = context.data
.Where(p => p.propertyInfo == valToMatch);
result.AddRange(matches.Select(t => t.Key));
}
return result;
}
This Method obviously doesn't work, so how can I do the same?
I am using SqlLite, so some answers given do not apply.
The whole problem is using propertyInfo the wrong way.
I tried various different approaches but no success.
This question is not a duplicate, because the suggested questions and their answers do not help much.
I like this question to be reopened.
I have found an answer myself I like to share.
ToString() method can not be translated into relevant SQL.
Try to use SqlFunctions.StringConvert(valToMatch) instead of valToMatch.ToString()
.ToString()
Doesn't works inside the Linq Query.
Inststed of .ToString() Function Use the following
SqlFunctions.StringConvert()
SEE THE FOLLOWING ANSWER
https://stackoverflow.com/a/3292773/3736442

Formatting Select Statement Using Dynamic Linq

I've been looking into this for quite some time now and cannot figure out a resolution. I Originally Tried formatting A dynamic linq Statement as you can see here in this post
I declared a class:
public class DynamicHelper
{
public string FormattedLink(string DisplayText, string ID)
{
return "" + DisplayText + "";
}
public string FormattedLink(string DisplayText, int ID)
{
return "" + DisplayText + "";
}
}
After I inserted a new type in DynamicLinq into the predefinedTypes
,typeof(DynamicHelper) //around line 635
I have a program which is attempting to Invoke the FormattedLink inside of a dynamic linq select:
using (var Model = new MK3Entities())
{
DynamicHelper Dh = new DynamicHelper();
var TOrigin = (Model.Titles.Where("ID > 19632")
.Select("new(ID, #0.FormattedLink(ExtTitleID, ID) as ExtTitleID )", Dh) as System.Collections.IEnumerable)
.Cast<dynamic>().Take(10).ToList();
Console.ReadKey();
}
When I execute this program I get a runtime exception "LINQ to Entities does not recognize the method 'System.String FormattedLink(System.String, Int32)' method, and this method cannot be translated into a store expression."
Any Ideas on how to fix this... I just need simple formatting from Dynamic Select.
The error message is pretty self explanatory. The database doesn't know how to translate that method into SQL. You need to fetch the information that the method needs in your database query and then call that function on the results, rather than in the query.
I'm not sure why you need it to be dynamic, it seems the solution you present is very overly complicated. I would write it as:
using (var Model = new MK3Entities())
{
DynamicHelper Dh = new DynamicHelper();
var TOrigin = Model.Titles
.Where("ID > 19632")
.Select(t => new { ID = t.ID, ExtTitleID = t.ExtTitleId })
.Take(10)
.ToList() // Execute SQL Statement
.Select(t => new {ID = t.ID, Link = nh.FormattedLink(ExtTitleID, ID)})
.ToList();
Console.ReadKey();
}
I'm returning an List<anonymous'1> object instead of a dynamic object (because I've never had the need for dynamic objects) so you can adjust it accordingly.
I just solved similiar problem few hours back.
YOu need ToList() that works with Dynamic linq. Check out this thread: Can't find property or field on a dynamic object
Just copy paste those to your project, and later:
var TOrigin = (Model.Titles.Where("ID > 19632")
.ToAnonymousList()
.Select("new(ID, #0.FormattedLink(ExtTitleID, ID) as
ExtTitleID )", Dh) as System.Collections.IEnumerable);

C# - convert anonymous type to observablecollection

I have a LINQ statement that returns an anonymous type. I need to get this type to be an ObservableCollection in my Silverlight application. However, the closest I can get it to a
List myObjects;
Can someone tell me how to do this?
ObservableCollection<MyTasks> visibleTasks = e.Result;
var filteredResults = from visibleTask in visibleTasks
select visibleTask;
filteredResults = filteredResults.Where(p => p.DueDate == DateTime.Today);
visibleTasks = filteredResults.ToList(); // This throws a compile time error
How can I go from a anonymous type to an observable collection?
Thank you
As Ekin suggests, you can write a generic method that turns any IEnumerable<T> into an ObservableCollection<T>. This has one significant advantage over creating a new instance of ObservableCollection using constructor - the C# compiler is able to infer the generic type parameter automatically when calling a method, so you don't need to write the type of the elements. This allows you to create a collection of anonymous types, which wouldn't be otherwise possible (e.g. when using a constructor).
One improvement over Ekin's version is to write the method as an extension method. Following the usual naming pattern (such as ToList or ToArray), we can call it ToObservableCollection:
static ObservableCollection<T> ToObservableCollection<T>
(this IEnumerable<T> en) {
return new ObservableCollection<T>(en);
}
Now you can create an observable collection containing anonymous types returned from a LINQ query like this:
var oc =
(from t in visibleTasks
where t.IsSomething == true
select new { Name = t.TaskName, Whatever = t.Foo }
).ToObservableCollection();
Something like this would do the job using type inference features:
private static ObservableCollection<T> CreateObservable<T>(IEnumerable<T> enumerable)
{
return new ObservableCollection<T>(enumerable);
}
static void Main(string[] args)
{
var oc = CreateObservable(args.Where(s => s.Length == 5));
}
You should just be able to do this:
visibleTasks = new ObservableCollection<MyTasks>(filteredResults);
Are you sure that your object is an ObservableCollection indeed? If yes, you can just cast: visibleTasks = (ObservableCollection)filteredResults;
Try:
var filteredResults = from visibleTask in visibleTasks
where(p => p.DueDate == DateTime.Today)
select visibleTask).ToList();
(filteredResults will contain your desired list)

Categories

Resources