"the operation cannot be completed because the dbcontext has been disposed entity framework" error is no var userinfo line - entity-framework

Error happens on the var userinfo line... I'm new to ASP.NET MVC and I'm trying to create a sample project to learn ASP.NET MVC, but got stuck here. I searched other posts with similar errors, but the issue was with not saving .
public ActionResult Login(LoginViewModel c)
{
using (db = new DBEntities())
if (!ModelState.IsValid)
{
return View(c);
}
// error happens on this line of code
var userinfo = db.e_usr.Where(m => m.usr_ename == c.Email && m.usr_pswd == c.Password).FirstOrDefault();
if (userinfo != null)
{
Session["LoginID"] = userinfo.usr_ename;
Session["LoginUser"] = userinfo.usr_pswd;
return Redirect("Home/Index");
}
return null;
}

You're missing a code block (by specifying { .... }) after your using statement. Therefore, the db is valid for only the next statement - the check whether your ModelState is valid or not. After that, the db variable is gone.
Change your code to:
public ActionResult Login(LoginViewModel c)
{
using (db = new DBEntities())
{ // <<<==== add this leading curly brace!
if (!ModelState.IsValid)
{
return View(c);
}
// Simplify your LINQ here - define the condition directly
// in the ".FirstOrDefault()" method
var userinfo = db.e_usr.FirstOrDefault(m => m.usr_ename == c.Email && m.usr_pswd == c.Password);
if (userinfo != null)
{
Session["LoginID"] = userinfo.usr_ename;
Session["LoginUser"] = userinfo.usr_pswd;
return Redirect("Home/Index");
}
return null;
} /// <<<==== add these closing curly braces
}

Related

Getting WorkbookPart from row

I am writing and extension for OpenXML like shown in the sample. I would like to avoid having to pass the WorkbookPart as parameter. Is there any way to get the WorkbookPart directly from the row?
public static string GetCellTextValue(this Row row, WorkbookPart workbookPart, string column)
{
var cells = row.Elements<Cell>();
var cell = cells.Where(p => p.CellReference == column + row.RowIndex.ToString()).FirstOrDefault();
if (cell.DataType != null)
{
if (cell.DataType == CellValues.SharedString)
{
int id = -1;
if (Int32.TryParse(cell.InnerText, out id))
{
SharedStringItem item = workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(id);
if (item.Text != null)
{
return item.Text.Text;
}
else if (item.InnerText != null)
{
return item.InnerText;
}
else if (item.InnerXml != null)
{
return item.InnerXml;
}
}
}
}
return string.Empty;
}
Unfortunately, none of the strongly-typed classes of the Open XML SDK (e.g., Workbook, Worksheet, Row) have properties pointing back to the OpenXmlPart (e.g., WorkbookPart, WorksheetPart) in which they are contained or any other part related to their immediate container. Unless you amend your API in other ways, you will have to pass that WorkbookPart.

how can I write generic queries in entity framework?

I have 3 methods these are same methods only some parameters will be change I want to write one method how can i write
public string method1(int id)
{
var getAllStudents = rep.Students.Where(e => e.StudentId == id).ToList();
foreach (var item in getAllStudents)
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
public string method2(int id)
{
var getAllTeachers = rep.Teachers.Where(e => e.TeacherId == id).ToList();
foreach (var item in getAllTeachers)
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
public string method3(int id)
{
var getAllClasses = rep.Classes.Where(e => e.ClassId == id).ToList();
foreach (var item in getAllClasses)
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
I think there is very easy way to write 1 method. the think is where parameter has different id..
Thanks.
Avoid conditional logic based on arguments. This leads to fragile code because every parameter combination has to be tested to be considered reliable. This leads to complex code that is easily prone to bugs. Having simpler single-purpose methods are typically much more reliable and easier to understand and maintain.
For instance given your example and assuming that "rep" was your instance's DbContext...
public bool IsActiveStudent(int id)
{
bool result = rep.Students.Any(x => x.StudentId == id && x.IsActive);
return result;
}
public bool IsActiveTeacher(int id)
{
bool result = rep.Teachers.Any(x => x.TeacherId == id && x.IsActive);
return result;
}
public bool IsActiveClass(int id)
{
bool result = rep.Classes.Any(x => x.ClassId == id && x.IsActive);
return result;
}
These can be essentially one-liners by simply returning the .Any() result. I tend to favour selecting the result into a variable first and returning it on a separate line since it makes it easier to breakpoint and inspect.
If you need to return a string for "Ok" vs. "Error" then:
return result ? "OK" : "Error";
Methods should strive to do one thing, and do it well. Easy to understand and troubleshoot if need be. Adding parameters and conditional code inside the method merely makes the code more volatile and leaves openings for bugs. In the end it doesn't make the code much shorter when the initial method could be simplified.
You can not overload methods if they signatures are the same.
You have two methods with the same signature:
public string checkexist(int id)
What you can do is to rename your methods, like this:
public interface WriteSomethingHere {
public boolean isStudentExist(int id);
public boolean isTeacherExist(int id);
public boolean isClassExist(int id);
}
I just found answer using generic repo
public T GetEntity<T>(int Id)
where T : class
{
using (MyEntities rpContext = new MyEntities())
{
return rpContext.Set<T>().Find(e => e.Id == Id);
}
}
after calling
var entityStudent = GetEntity<Student>(1);
var entityTeacher = GetEntity<Teacher>(1);
var entityClasses = GetEntity<Classes>(1);
You have Create Enumeration
Public Enum ParameterStaus:short
{
Student=1,
Teacher=2,
Classess=3
}
public string method2(int id.ParameterStatus status)
{
if(status==ParameterStatus.Teacher)
{
var getAllTeachers = rep.Teachers.Where(e => e.TeacherId == id).ToList();
foreach (var item in getAllTeachers )
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
}
Else if(status==ParameterStatus.Student)
{
var getAllStudents = rep.Students.Where(e => e.StudentId == id).ToList();
foreach (var item in getAllStudents)
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
Else
{
var getAllClasses = rep.Classes.Where(e => e.ClassId == id).ToList();
foreach (var item in getAllClasses)
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
}

EF6 Convert IQueryable to DbQuery

In Entity framework 6, when running the overload of the Include method that uses lambda expression to the context:
Context.SomeEntity.Include(x => x.MyOtherEntity))
it returns an IQueryable, whereas when we use the one that uses string:
Context.SomeEntity.Include("MyOtherEntity")
it returns a DbQuery.
I need to return a DbQuery and don't want to use the string overload so that I can get inclusion errors at compile time.
How can I return a DbQuery after using the include with the lambda?
I believe you can't convert an IQueryable to a DbQuery. However, you can use this code to pass in an expression and get the required string.
Be sure to write some unit tests for this and adapt the method for your needs. I have not tested it properly yet.
public static string GetMemberName<T>(this Expression<Func<T>> expression)
{
MemberExpression memberExp;
if (!TryFindMemberExpression(expression.Body, out memberExp))
return string.Empty;
var memberNames = new Stack<string>();
do
{
memberNames.Push(memberExp.Member.Name);
}
while (TryFindMemberExpression(memberExp.Expression, out memberExp));
return string.Join(".", memberNames.ToArray());
}
private static bool TryFindMemberExpression(Expression exp, out MemberExpression memberExp)
{
memberExp = exp as MemberExpression;
if (memberExp != null)
{
return true;
}
if (IsConversion(exp) && exp is UnaryExpression)
{
memberExp = ((UnaryExpression)exp).Operand as MemberExpression;
if (memberExp != null)
{
return true;
}
}
return false;
}
private static bool IsConversion(Expression exp)
{
return (exp.NodeType == ExpressionType.Convert || exp.NodeType == ExpressionType.ConvertChecked);
}

Breeze not updating after save. View with 1 to 0..1 relationship to table

I have a view and a table that has a 1 to 0..1 relationship. Everything works fine if there is a record in the table but I'm having trouble when I create a record.
Here is the code:
function orderVerified(order) {
if (order.approvals) {
order.approvals.isApproved = true;
} else {
datacontext.order.createApproval(order.id, order.type);
}
save(order);
}
function createApproval(id, type) {
return this.manager.createEntity("SalesOrdersApproval",
{id: id, type: type, isApproved: true});
}
This works and if if a record doesn't exist my database is updated as I would expect. The problem is when the else condition is met and I need to create the record my UI isn't updated.
I tried changing my orderVerified function to this but the new line throws an error:
function orderVerified(order) {
if (order.approvals) {
order.approvals.isApproved = true;
} else {
var a = datacontext.eaorder.createApproval(order.id, order.type);
order.approvals = a; //this line throws the error below
}
save(order);
}
Error:
Save failed: Unable to update the EntitySet 'vwEaSalesOrdersPickupsCombined' because it has a DefiningQuery and no element exists in the element to support the current operation.
Any suggestions?
I added this on the server and now the line
order.approvals = a;
no longer throws the error and my UI updates as expected.
protected override bool BeforeSaveEntity(EntityInfo entityInfo)
{
var entity = entityInfo.Entity;
if (entity is EaSalesOrdersPickupsCombined) //the name of the view
{
return false; //don't update
}
return true;
}

Merge Self-tracking entities

Graph of objects stored in the database and the same object graph is serialized into a binary package. Package is transmitted over the network to the client, then it is necessary to merge data from the package and data from the database.
Source code of merge:
//objList - data from package
var objectIds = objList.Select(row => row.ObjectId).ToArray();
//result - data from Database
var result = SomeService.Instance.LoadObjects(objectIds);
foreach (var OSobj in objList)
{
var obj = result.Objects.ContainsKey(OSobj.ObjectId)
? result.Objects[OSobj.ObjectId]
: result.Objects.CreateNew(OSobj.ObjectId);
var targetObject = result.DataObjects.Where(x => x.ObjectId == OSobj.ObjectId).FirstOrDefault();
targetObject.StopTracking();
var importedProperties = ImportProperties(targetObject.Properties, OSobj.Properties);
targetObject.Properties.Clear();
foreach (var property in importedProperties)
{
targetObject.Properties.Add(property);
}
targetObject.StartTracking();
}
return result;
And code of ImportProperties method:
static List<Properties> ImportProperties(
IEnumerable<Properties> targetProperties,
IEnumerable<Properties> sourceProperties)
{
Func<Guid, bool> hasElement = targetProperties
.ToDictionary(e => e.PropertyId, e => e)
.ContainsKey;
var tempTargetProperties = new List<Properties>();
foreach (var sourceProperty in sourceProperties)
{
if (!hasElement(sourceProperty.PropertyId))
{
sourceProperty.AcceptChanges();
tempTargetProperties.Add(sourceProperty.MarkAsAdded());
}
else
{
sourceProperty.AcceptChanges();
tempTargetProperties.Add(sourceProperty.MarkAsModified());
}
}
return tempTargetProperties;
}
Server save incoming changes like this :
_context.ApplyChanges("OSEntities.Objects", entity);
_context.SaveChanges(SaveOptions.DetectChangesBeforeSave);
When the server tries to save the changes occur exception:
AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
But if I change the code of ImportProperties method, the error does not occur and the changes are saved successfully:
static List<Properties> ImportProperties(
IEnumerable<Properties> targetProperties,
IEnumerable<Properties> sourceProperties)
{
Func<Guid, bool> hasElement = targetProperties.ToDictionary(e => e.PropertyId, e => e).ContainsKey;
var tempTargetProperties = new List<Properties>();
foreach (var sourceProperty in sourceProperties)
{
if (!hasElement(sourceProperty.PropertyId))
{
var newProp = new Properties
{
ElementId = sourceProperty.ElementId,
Name = sourceProperty.Name,
ObjectId = sourceProperty.ObjectId,
PropertyId = sourceProperty.PropertyId,
Value = sourceProperty.Value
};
tempTargetProperties.Add(newProp);
}
else
{
var modifiedProp = new Properties
{
ElementId = sourceProperty.ElementId,
Name = sourceProperty.Name,
ObjectId = sourceProperty.ObjectId,
PropertyId = sourceProperty.PropertyId,
Value = sourceProperty.Value
};
modifiedProp.MarkAsModified();
tempTargetProperties.Add(modifiedProp);
}
}
return tempTargetProperties;
}
Why is there an exception?
When you transport an object graph (Entity with n-level deep navigation properties) to a client application the entities will record any changes made in their respective change trackers. When entity (or object graph) is sent back to the server side of the application basically all you need to do is:
try
{
using(Entities context = new Entities())
{
context.ApplyChanges(someEntity);
context.SaveChanges();
}
}
catch
{
...
}
I don't see the need of all the code above you posted. What are you trying to achieve with that code?