Entity Framework Access multiple select statements - entity-framework

my stored procedure returns 3 select statements. using entity framework how can access the particular select statement.
In ADO.Net using "DATASET" we can access particular table. like
DataSet ds = GetApplicationSummary(appId);
DataTable dt = ds.Tables[0];
now we can access the Table[0] of data. same as next two tables.
Using EntityFramework how can access 3 select statements data. please can any help this.

You can access multiple result sets by GetNextResult. Here's a code sample from Microsoft.
using (var db = new BlogEntities())
{
var results = db.GetAllBlogsAndPosts();
foreach (var result in results)
{
Console.WriteLine("Blog: " + result.Name);
}
var posts = results.GetNextResult<Post>();
foreach (var result in posts)
{
Console.WriteLine("Post: " + result.Title);
}
Console.ReadLine();
}
Check out this by Microsoft for more information.

Related

Sort entities in foreign key dependency order

I am working on a mechanism to seed a collection of tables via EF Core. How can I sort a DbContext's entities in order of foreign key dependencies? Since some tables have foreign keys, some tables need to be seeded before others. It seems like there would be a simple API for performing this sort, but all I have been able to find are a couple complex recursive T-SQL implementations.
I am sure there is a common solution for this type of problem that is prevalent, I just have been unable to locate it / know how to search for it.
Update:
Because EF Core doesn't seem to support Merge/Upsert/AddOrUpdate yet, I am going down the path of a database-specific (MySQL family in this case) raw SQL query. So, I have a method like below that I want to call for a collection of entities, but I need to call this method in order of the TEntityType's foreign key dependencies. Since it is a raw SQL query and not an EF API, per se, I don't think EF can auto-magically update tables in the correct dependency order (in response to #Gert's comment).
private static void InsertOnDuplicateKeyUpdate<TEntityType>(DbContext dbContext) where TEntityType : class
{
var entityType = dbContext.Model.FindEntityType(typeof(TEntityType));
var properties = GetPropertiesLessValueGeneratedTimestamps(entityType);
var columns = string.Join(", ", properties.Select(x => x.Name));
var values = CreateValues<TEntityType>(properties);
var updates = CreateUpdates(properties);
var rawSqlString = "INSERT INTO " + entityType.Relational().TableName + " (" + columns + ") VALUES " +
values + " ON DUPLICATE KEY UPDATE " + updates;
dbContext.Set<TEntityType>().FromSql(rawSqlString);
dbContext.SaveChanges();
}
Entity Framework Core contains all information needed to sort entity types based on foreign key dependencies. The only issue I found when using EF Core as a source of table order is that same table references will need to be handled differently - whether it might be for example allowing inserting identifiers, disabling table triggers or some other way.
To grab a list of entity types from which you can get table names, DbSet etc, use the following function:
private IList<IEntityType> GetDependentTables(IModel model)
{
var copied = new List<IEntityType>();
var tables = model.GetEntityTypes().Where(x => x.GetKeys().Any()).ToList();
while (tables.Count > 0)
{
var copiedCount = copied.Count;
for (var i = 0; i < tables.Count; i++)
{
var table = tables[i];
if (table.GetForeignKeys().All(x => copied.Contains(x.PrincipalEntityType) || x.DeclaringEntityType == x.PrincipalEntityType))
{
copied.Add(table);
tables.RemoveAt(i);
break;
}
}
if (copiedCount == copied.Count)
{
throw new InvalidOperationException("Circular foreign keys found in remaining tables: " + string.Join(",", tables.Select(x => x.Name)));
}
}
return copied.Where(x => x.BaseType == null).ToList();
}
usage:
var tableEntityTypes = GetDependentTables(myDbContext.Model);

Not able to use IN query in LINQ with Entity Framework

I am using EF Framework to retrieve the data from SQL DB.
Sub Request Table looks like below:
In this table "org_assigneddept" is foreign key to another Department Table.
I have list of Departments as Input and I want to retrieve only those rows from DB whose org_assigneddept is matching the list.
Please find my whole code:-
private List<EventRequestDetailsViewModel> GetSummaryAssignedDeptEventRequests(List<EmpRoleDeptViewModel> vmDept)
{
List<EventRequestDetailsViewModel> vmEventRequestDeptSummary = new List<EventRequestDetailsViewModel>();
RequestBLL getRequestBLL = new RequestBLL();
Guid subRequestStatusId = getRequestBLL.GetRequestStatusId("Open");
using (var ctxGetEventRequestSumm = new STREAM_EMPLOYEEDBEntities())
{
vmEventRequestDeptSummary = (from ers in ctxGetEventRequestSumm.SubRequests
where vmDept.Any(dep=>dep.DeptId == ers.org_assigneddept)
select new EventRequestDetailsViewModel
{
SubRequestId = ers.org_subreqid
}).ToList();
}
}
It is giving the following error at the LINQ Query level:-
System.NotSupportedException: 'Unable to create a constant value of
type 'Application.Business.DLL.EmpRoleDeptViewModel'. Only primitive
types or enumeration types are supported in this context.'
Please let me know as how can I achieve the result
You cannot pass the department VMs to SQL, it doesn't know what those are.
// Extract the IDs from the view models.. Now a list of primitive types..
var departmentIds = vmDept.Select(x => x.DeptId).ToList();
then in your select statement...
..
where departmentIds.Contains(id=> id == ers.org_assigneddept)
..

Entity Framework: A better way to update lots of table records

I am new at Entity framework, and curious what the best way would be to update all tables with records of new data. I have a method which returns a list of objects with updated records. Most of the information stays the same; just two fields will be updated.
Currently I created two ways of doing that update.
The first one is to get data from the database table and iterate from both Lists to find a match and update that match:
var previousDatafromTable= db.Widgets.ToList();
var newDataReturnedFromMethod =.......
foreach (var d in previousDatafromTable)
{
foreach (var l in newDataReturnedFromMethod )
{
if (d.id == l.id)
{
d.PositionColumn = l.PositionColumn;
d.PositionRow = l.PositionRow;
}
}
The second one is:
foreach (var item in newDataReturnedFromMethod )
{
var model = db.Widgets.Find(item.id);
model.PositionColumn = item.PositionColumn;
model.PositionRow = item.PositionRow;
}
I am iterating through the updated data and updating my database table by ID.
So I am interested to know which method is the better way of doing this, and maybe there is an option in Entity Framework to measure the performance of these two tasks? Thanks for your time in answering.
Neither is really efficient.
The first option loops through newDataReturnedFromMethod for each iteration of previousDatafromTable. That's a lot of iterations.
The second options probably executes a database query for each iteration of newDataReturnedFromMethod.
It's far more efficient to join:
var query = from n in newDataReturnedFromMethod
join p in previousDatafromTable on n.id equals p.id
select new { n,p };
foreach (var pair in query)
{
pair.p.PositionColumn = pair.n.PositionColumn;
pair.p.PositionRow = pair.n.PositionRow;
}
EF doesn't have built-in performance measurements. You'd typically use a profiler for that, or the StopWatch class.

How to get List of all tables in the Entity data framework?

I need to get the list of All tables in the Entity Data Framework.
I know that in Linq2SQL we can use something like this.
var dataContext = new DataContext();
var dataContextTableNames = (from tables in dataContext.Mapping.GetTables()
select tables.TableName).ToList();
But, I need to get list of all tables in Entity Data Framework. There is any work around to get similar list in Entity Data Framework.
Thanks in advance.
[Edit]
Perhaps this can be of use to find the number of objects in Storage space
var count = GetEntitySetCount(myObjectContext.MetadataWorkspace);
public static int GetEntitySetCount(MetadataWorkspace workspace)
{
var count = 0;
// Get a collection of the entity containers from storage space.
var containers = workspace.GetItems<EntityContainer>(DataSpace.SSpace);
foreach(var container in containers)
{
//Console.WriteLine("EntityContainer Name: {0} ",
// container.Name);
foreach(var baseSet in container.BaseEntitySets)
{
if(baseSet is EntitySet)
{
count++;
//Console.WriteLine(
// " EntitySet Name: {0} , EntityType Name: {1} ",
// baseSet.Name, baseSet.ElementType.FullName);
}
}
}
return count;
}
To retrieve the number of tables in the database, you can do the following in .Net 4.0
myObjectContext.ExecuteStoreQuery<int>(
"SELECT COUNT(*) from information_schema.tables WHERE table_type = 'base table'");
Using .Net 3.5
var connection = ((EntityConnection)myObjectContext.Connection).StoreConnection as SqlConnection;
var cmd = new SqlCommand("SELECT COUNT(*) from information_schema.tables WHERE table_type = 'base table'", connection);
connection.Open();
var count = (int)cmd.ExecuteScalar();
connection.Close();

Using ObjectQuery Include and using a nested where clause

Using entity framework, I'm trying to get back a customer with order details but I want to filter out those Orders that are active.
Customer is our EntityObject which has a collection of Order EntityObjects. CustomerDetails is our ObjectContext.
The code below will attach all orders but I want to filter and only attach those that are active. (Order.active == true). How can I do this?
I know Include builds up a nested query statement (I can observe by using .ToTraceString().) I was hoping to attach a Where clause to this nested select statement or the Include.
Customer cust;
CustomerDetails custTable = new CustomerDetails();
cust = custTable.Customer
.Where("it.cust_id = " + id)
.Include("Order") // But we only want Order.active == true!!!
.ToList().First();
Untested, but might work?
var temp = custTable.Customer.Where("it.cust_id = " + id).Include("Order");
cust = (from t in temp
where t.Order.active == true
select t).ToList().First();