I currently have a Class which uses the function as such:
var txbl = test.search_bustype("SUP", "Name");
or
foreach(string toWorkWith in test.search_bustype("SUP", "Name")){ // each one }
However, for every Column I want to search using a function, I have to create a separate function.
ie: Columns - bustype, companyID - Would have to have separate functions to search.
My current code is:
public Array search_bustype(string match, string forthat)
{
db = new rkdb_07022016Entities2();
var tbl = (from c in db.tblbus_business select c).ToArray();
List<string> List = new List<string>();
int i = 0;
foreach (var toCheck in tbl)
{
if (toCheck.BusType.ToString() == match)
{
if (forthat == "Name")
{
List.Add(toCheck.Name);
}
}
i++;
}
return List.ToArray();
}
Is there anyway to possibly, like php actually send the query to the function and then run it there? I haven't been able to find many sources about how to build a secure infrastructure with Entity so I am wondering if anyone knows any way of maybe creating a skeleton method with this framework.
Thanks in advance!
Okay so I stumbled on the Frameworks sources and actually now understand that the Framework itself implements the Skeleton method.
You simply only refer to each query inside the (from c in......
I'll have to look further into how this infrastructure works before I can understand how to further implement functions.
Thank-you for your time however! I will close this.
Related
consider the following scenario:
public class DBEntry {
public string Id;
}
public class ComputedEntry {
public string Id;
public int ComputedIndex;
}
IQueryable<DBEntry> databaseQueryable; // Somewhere hidden behind the API
IQueryable<ComputedEntry> entryQueryable; // Usable with the API
Let's assume each DBEntry has a unique Id and not much else. A ComputedEntry has a 1:n relationship with DBEntry, meaning that a DBEntrycan be expanded into more than a single ComputedEntryduring execution of the query.
Now, I am trying to query entryQueryable to get a range of computed indices, e.g:
entryQueryable.Where(dto => dto.ComputedIndex < 10 && dto.Id == "some-id");
What I'm looking for is a way of separating the given query expression to only push down the relevant parts of the query to the databaseQueryable. In the example above something like this should happen (probably in the implementation of IQueryableProvider.Execute when using the entryQueryable):
var results = databaseQueryable.Where(e => e.Id == "some-id").ToList();
int i = 0;
return results.Select(e => new ComputedEntry(e.Id, i++));
So basically I'd like the query to be separated and the relevant/compatible parts should be pushed down to the databaseQueryable.
The obvious question would be: How should I approach this? I tried to figure out a way of separating the expression with an ExpressionVisitor, but haven't been very successful here and it seems like this is a rather complex task.
Any ideas? Maybe there is an already existing method of optimizing/translating the query I am not aware of? I have looked through the documentation but couldn't find anything useful here.
Many thanks for your suggestions!
I have been working in a project which uses Entity Framework as the ORM data model to connect to the SQL database and retrieve data.
Now the basic query which is used to retrieve data is like this
ProjectDataContext dataContext = new ProjectDataContext();
var result = (from project in dataContext.Projects
select project).ToList();
Or in lambda
List<Project> lstprojects = dataContext.Projects.Take(10);
Now I would like to pass the table name dynamically based on some input parameter. How can I achieve that?
The way I am currently doing it is a bit messy.
if(tableName = "A")
{
List<A> lstOfA = dataContext.A.Take(10);
}
else if(tableName = "B")
{
List<B> lstOfB = dataContext.B.Take(10);
}
and so on...
My question is if there is a neat and clean way to do this without writing so many if else because I understand it may cause performance issues in future.
Thanks
Ok after some trial and error I have been able to do it like this-
var type = Type.GetType("A");
context.Set(type).Load();
var result = context.Set(type).Local.Cast<object>().ToList();
Hope it helps.`
I'm trying to accomplish 2 things with the below snippet of code (from ApplicationDataService.lsml.cs in the server project of my Lightswitch 2013 solution).
partial void Query1_PreprocessQuery(ref IQueryable<CandidateBasic> query)
{
query = from item in query where item.CreatedBy == this.Application.User.Name select item;
}
partial void CandidateBasics_Validate(CandidateBasic entity, EntitySetValidationResultsBuilder results)
{
var newcandidateCount = this.DataWorkspace.ApplicationData.Details.GetChanges().AddedEntities.OfType<CandidateBasic>().Count();
var databasecandidateCount = this.CandidateBasics.GetQuery().Execute().Count();
const int maxcandidateCount = 1;
if (newcandidateCount + databasecandidateCount > maxcandidateCount)
{
results.AddEntityError("Error: you are only allowed to have one candidate record");
}
}
Firstly, I want to make sure each user can only see things that he has made. This, together with a preprocess query on the table in question, works perfectly.
The next bit is designed to make sure that each user can only create one record in a certain table. Unfortunately, it seems to be looking at the whole table, and not the query I made that shows only the user's own records.
How can I get that second bit of code to limit only the user's own records, and not the global table?
You're not actually calling that query though are you? Your query is called Query1 based on the code provided yet you don't seem to be calling it. I'd do something like:
int count = DataWorkspace.ApplicationData.Query1().Count();
I would like to create a drop down similar to the drop down for sql data types in the data mapping section in the Import/Export Wizard in Sql Management Studio.
Does anyone know how to do this without writing custom code to do so? Would there be a method call in System.Data.Sql that would perform this?
Just for posterity, this is not that hard to do - run this in Linqpad with a reference to System.Data:
void Main()
{
Console.WriteLine(GetSqlTypes());
}
Dictionary<string,Type> GetSqlTypes()
{
var types=new Dictionary<string,Type>();
var a = Assembly.Load("System.Data");
foreach (var sqlType in a.GetTypes().Where(t=>t.Namespace=="System.Data.SqlTypes"
&& t.Name.StartsWith("Sql")
&& !t.Name.Contains("Exception")
&& !t.Name.Contains("Schema")
&& !t.Name.Contains("Stream")))
{
types.Add(sqlType.Name,sqlType);
}
return types;
}
So you can just bind your dropdown to GetSqlTypes:
ddlTypes.DataSource = GetSqlTypes();
ddlTypes.DataTextField = "Value";
ddlTypes.DataValueField = "Key";
ddlTypes.DataBind();
Of course this is a pure brute-force hack and no doubt someone else has a more elegant way to do it, but this will at least get you up and running.
System.Enum.GetValues(typeof(System.Data.SqlDbType));
There is no built in method to do that.
I have two tables Studies and Series. Series are FK'd back to Studies so one Study contains a variable number of Series.
Each Series item has a Deleted column indicating it has been logically deleted from the database.
I am trying to implement a Deleted property in the Study class that returns true only if all the contained Series are deleted.
I am using O/R Designer generated classes, so I added the following to the user modifiable partial class for the Study type:
public bool Deleted
{
get
{
var nonDeletedSeries = from s in Series
where !s.Deleted
select s;
return nonDeletedSeries.Count() == 0;
}
set
{
foreach (var series in Series)
{
series.Deleted = value;
}
}
}
This gives an exception "The member 'PiccoloDatabase.Study.Deleted' has no supported translation to SQL." when this simple query is executed that invokes get:
IQueryable<Study> dataQuery = dbCtxt.Studies;
dataQuery = dataQuery.Where((s) => !s.Deleted);
foreach (var study in dataQuery)
{
...
}
Based on this http://www.foliotek.com/devblog/using-custom-properties-inside-linq-to-sql-queries/, I tried the following approach:
static Expression<Func<Study, bool>> DeletedExpr = t => false;
public bool Deleted
{
get
{
var nameFunc = DeletedExpr.Compile();
return nameFunc(this);
}
set
{ ... same as before
}
}
I get the same exception when a query is run that there is no supported translation to SQL. (
The logic of the lambda expression is irrelevant yet - just trying to get past the exception.)
Am I missing some fundamental property or something to allow translation to SQL? I've read most of the posts on SO about this exception, but nothing seems to fit my case exactly.
I believe the point of LINQ-to-SQL is that your entities are mapped for you and must have correlations in the database. It appears that you are trying to mix the LINQ-to-Objects and LINQ-to-SQL.
If the Series table has a Deleted field in the database, and the Study table does not but you would like to translate logical Study.Deleted into SQL, then extension would be a way to go.
public static class StudyExtensions
{
public static IQueryable<study> AllDeleted(this IQueryable<study> studies)
{
return studies.Where(study => !study.series.Any(series => !series.deleted));
}
}
class Program
{
public static void Main()
{
DBDataContext db = new DBDataContext();
db.Log = Console.Out;
var deletedStudies =
from study in db.studies.AllDeleted()
select study;
foreach (var study in deletedStudies)
{
Console.WriteLine(study.name);
}
}
}
This maps your "deleted study" expression into SQL:
SELECT t0.study_id, t0.name
FROM study AS t0
WHERE NOT EXISTS(
SELECT NULL AS EMPTY
FROM series AS t1
WHERE (NOT (t1.deleted = 1)) AND (t1.fk_study_id = t0.study_id)
)
Alternatively you could build actual expressions and inject them into your query, but that is an overkill.
If however, neither Series nor Study has the Deleted field in the database, but only in memory, then you need to first convert your query to IEnumerable and only then access the Deleted property. However doing so would transfer records into memory before applying the predicate and could potentially be expensive. I.e.
var deletedStudies =
from study in db.studies.ToList()
where study.Deleted
select study;
foreach (var study in deletedStudies)
{
Console.WriteLine(study.name);
}
When you make your query, you will want to use the statically defined Expression, not the property.
Effectively, instead of:
dataQuery = dataQuery.Where((s) => !s.Deleted);
Whenever you are making a Linq to SQL query, you will instead want to use:
dataQuery = dataQuery.Where(DeletedExpr);
Note that this will require that you can see DeletedExpr from dataQuery, so you will either need to move it out of your class, or expose it (i.e. make it public, in which case you would access it via the class definition: Series.DeletedExpr).
Also, an Expression is limited in that it cannot have a function body. So, DeletedExpr might look something like:
public static Expression<Func<Study, bool>> DeletedExpr = s => s.Series.Any(se => se.Deleted);
The property is added simply for convenience, so that you can also use it as a part of your code objects without needing to duplicate the code, i.e.
var s = new Study();
if (s.Deleted)
...