Querying conceptual model with Entity SQL - c#

Thought I read somewhere that you in fact can query your conceptual model with Entity Sql, using string based queries as such:
class DBSetTest<T> : List<T>
{
DBEntities db = new DBEntities();
public DBSetTest()
{
ObjectQuery<T> test = new ObjectQuery<T>("SELECT Name FROM Sessions WHERE Name = 'sean'", db);
foreach (var v in test)
{
this.Add(v);
}
}
}
Where 'Sessions' is a custom Entity Type I defined with a 'DefiningQuery'. I would otherwise query it with normal linq syntax. Does Entity SQL only query the store or can it query my conceptual model just like LINQ-to-Entities does? If so not sure I have the right syntax, since it probably isn't sql syntax. My goal is to create a sort of custom generic list here, where I can write dynamic queries against my conceptual model.
I get the following error:
'Name' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly. Near simple identifier, line 1, column 43.

I think, It is not valid Entity SQL sintax,
probably you must add some keyword like this :
SELECT VALUE s.Name FROM your_ObjectContext_name.Sessions AS s WHERE s.Name = 'sean'

The error you get says that you must put it. before Name, like this:
"SELECT it.Name FROM Sessions WHERE it.Name = 'sean'"

Related

Pass string of "<TableName>.<ColumnName>" as a Where() condition generates error: "No property or field '<TableName>' exists in type '<TableName>'"

Currently, I build query statement by using dynamic-linq library.
And I have an issue when I execute this query:
query = query.Where("Table1.Column2.Contains(#0)", new string[] { "test" });
FYI:
Table1: a table name in my database
Column2: a column name inside Table1
As a result, it throws an error:
No property or field 'Table1' exists in type 'Table1'
I have made sure, the naming are correct. A friend of mine, he also uses exactly the same library and he can execute it successfully in different database, MSSQL 2014. I am using MSSQL 2008.
When I try to do it in different way like:
query = query.Where("Column2.Contains(#0)", new string[] { "test" });
It works fine..
I am wondering, in my case, I have to use the first approach instead. That's why, what am I doing wrong with it?
My understanding is that Dynamic Linq is still operating on objects, not passing what you write directly through to SQL? So you can only add conditions on things that are properties of the underlying object. Now these may be defined as being populated from various columns in a database, but they don't have to be...
I think you're basically trying to do this sort of thing:
class x
{
int SomeProperty{get;set;}
}
...
...
var instance = new x();
instance.SomeProperty = 1;
//compile Error: x is not a property of an instance of x
if (instance.x.SomeProperty==1)
{
// ..Do things
}

How to return anonymous objects as the result of LINQ-to-SQL queries

I'm creating a tool that allows users to run SQL SELECT commands and the results will be displayed in an HTML table. I am using ASP.NET Core MVC and trying to avoid using SqlConnection/SqlCommand/etc. if possible, going straight through DataContext.
For example, if someone types in
"SELECT Id, Name FROM Table"
and the results are
Id | Name
------------
1 | 'Bob'
2 | 'Harry'
I want Json(results) to be
[
{ Id: 1, Name: "Bob" },
{ Id: 2, Name: "Harry"}
]
where I suppose that results would be of type IEnumerable<object>.
What I have now is a method in my repository like
public List<object> RunQuery(string query)
{
using(MyDbContext context = new MyDbContext())
{
return context.MiscTable.FromSql<object>(query).ToList();
}
}
but then I get an exception like
$exception {System.InvalidOperationException: The required column 'SomeColumn' was not present in the results of a 'FromSql' operation.
where SomeColumn is some column on MiscTable. So apparently I can only query specific tables using FromSql. Is there a way to do what I'm trying to do?
You can't use .FromSqlwith ad-hoc models. The fields returned from the query must exactly match the model (no missing fields).
Ad-hoc/non-entity models are not supported yet in EF Core but are on the roadmap.
https://github.com/aspnet/EntityFramework/wiki/Roadmap
Raw SQL queries for non-Model types allows a raw SQL query to be used to populate types that are not part of the model (typically for denormalized view-model data).
Also anonymous classes can't be returned, since their type is only know at compile type. You should create models for your entities in the database (usually 1 model per table, but you can also have more models in one table via inheritance). That's what ORM is for.
If you just want raw queries, use ADO.NET directly. ORMs are there for mapping tables to classes/objects.
I believe you can use .Include() to add additional tables to the dbset your FromSql operates on. Check out this link for examples and additional context.
https://learn.microsoft.com/en-us/ef/core/querying/raw-sql#composing-with-linq
From your example, your query might look like this:
return context.MiscTable.Include(t => t.RelatedTable).FromSql<object>(query).ToList();
Disclaimer: I didn't actually try this, so I'm not sure it will actually work. But it seems reasonable.

access a Database scalar value function in Entity framework 6 within linq

What steps i should follow to use the following sql scalar value function within entity framework.
select dbo.GetDefaultAccount(5,1,48)
I tried creating a static class under the same namespace of the edmx and defining the function as following
[EdmFunction("Model.Store", "GetDefaultAccount")]
public static int? GetDefaultAccount(int id, Int16 type, int assocId)
{
throw new NotSupportedException();
}
While accessing it from linq like below
var Accountno = (from s in dbcontext.TranSetups select new { Accountno = CutomEdmxFunctions.GetDefaultAccount(5, 1, 48) })
.FirstOrDefault().Accountno;
I get the following error
cannot be translated into a LINQ to Entities store expression because no overload matches the passed arguments
Thanks
Unfortunately, working scalar-valued functions in Entity Framework is not as easy as it supposed to be. After a long googling I found only two methods to work with scalar-valued functions, best described here, but remember: all edits to the .edmx file will be lost when you update the EDM from the database. You will have to re-edit the .edmx file each time. Good luck.

Get EF Table by type (parameter)

I have this very old database with all the tables named like this ANAGT*postfix* and all the columns are namede like this *prefix*_*column name*.
I have to query all the tables with the same query more or less, but obviously the names of the columns are all different so I would have to do some trick with a sql statement with the strings, but I prefer to get a strong typed exception in case of errors using the EF.
So I've created some interfaces and implemented them on partial classes from the EF model
public partial class *table name* : IIdentificable, ICountabile {}
IIdentificabile means that there's a method with a common name that gets all the ids (instead of query *prefix*_ID), so when I'll have to query the table I'll just have to do
var result = from elem in myContext.[Table]
where elem.GetId() == 1
select elem;
I've created a generic method that gets all the types from a certain interface (IIdentificable for instance) and now I have to get the EF table by type.
var tablesType = typeof(myModel).Assembly
.GetExportedTypes()
.Where(t=>t.IsAssignableFrom(typeof(T)));
foreach(Type t in tablesType){
var query = from elem in myContext.GetTable(t) //and here's what I can't do
select elem.GetId() == 1
select elem;
}
I think another approach may be better. In the EF Model you can rename the C# Objects and properties. Using the properties of a selected property in the model, you can change the Name to get rid of the prefix. Similarly, the properties of a selected table in the model allow you to change both the Entity Set name (the name of a collection of them) and the Name of the C# class. The names of the underlying database tables and columns aren't affected.

Exception using Linq query with EF Code first on SQL Server table

I have setup EF code first against my DB (specifically, a table called tblExpenseMain).
In my controller I'm trying to pass an instance of my 'ExpenseMain' class over to the view so the details can be presented. Manually creating an instance and passing it works:
ExpenseMain em = new ExpenseMain { Card_Number = "123", UniqueID_ERLineID = "blah", Item_Amount = 500, Item_Expense_Type = "something"};
return View("_Basic");
But trying to query it with LINQ like so gives me an exception:
ExpenseMain model = (from e in db.ExpenseMains
where e.UniqueID_ERLineID == transUniqueID
select e).SingleOrDefault();
It tells me to check the innerexception to find the problem. I surrounded it with a try/catch and the innerexception message was:
e.InnerException.Message = "Invalid object name 'dbo.ExpenseMains'."
Any suggestions on what I'm doing wrong? I was hoping that the linq query would just grab my single instance and go from there. Changing 'Expensemain model' to 'var model' and looking at what the var becomes, confirms it becomes an 'Expensemain' anyway.
Thanks
If your class name is different from the table name, then you have to configure EF to map them. You can use the table attribute and give the table name.
[Table("tblExpenseMain")]
public class ExpenseMain
{
//properties
}
Do you have several data access layers in your sulotion? Could it be that ExpenseMain is an old Entity, not generated from EF. Double check that there are no tblExpenseMain entity aswell or similar.
Hope this helps.
Looks like u have 2 classes here: ExpenseMain and ExpenseMains

Categories

Resources