how can I write generic queries in entity framework? - 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";
}
}

Related

Don't execute assignment if value is null

I am still coming up to speed with dart and wanted to know if there was an easier way to not execute a statement if the value is null. See example below:
I can always do the if statements below for setting field3 and field4, but felt like something like field5 should work. But when I try to do that, it complains that a null check operator is used on a null value.
Also I don't want to change the Map to have a dynamic value.
Is there a single one liner to do what I am trying to do, or do I just need to check for null before setting the value.
Map<String, Object> myMap = {};
print('running now');
try {
myMap['field1'] = DummyClass.getString('hello');
myMap['field2'] = DummyClass.getString('good');
//Is there a more concise way to do this than the 2 options below?
if (DummyClass.getOptionalString('goodbye') != null) {
myMap['field3'] = DummyClass.getOptionalString('goodbye')!;
}
String? temp = DummyClass.getOptionalString('go');
if (temp != null) {
myMap['field4'] = temp;
}
// This gives an error 'null check operator used on a null value'
// myMap['field5'] ??= DummyClass.getOptionalString('to')!;
} catch (e) {
print('error condition, $e');
}
print(myMap);
}
class DummyClass {
static String getString(String? strParam) {
String? retString = getOptionalString(strParam);
if (retString == null) {
throw ('nulls are not allowed');
}
return retString;
}
static String? getOptionalString(String? strParam) {
if (strParam == null || strParam.length < 3) {
return null;
}
return strParam;
}
}
There's no built-in way to do what you want, but you could write a function (or extension method) to do it. For example:
extension MapTrySet<K, V> on Map<K, V> {
void trySet(K key, V? value) {
if (value != null) {
this[key] = value;
}
}
}
and then you could do:
myMap.trySet('field3', DummyClass.getOptionalString('goodbye'));
myMap.trySet('field4', DummyClass.getOptionalString('go'));
Alternatively, if you really want to use normal Map syntax, you could create your own Map class that has a void operator []=(K key, V? value) override and does nothing when the value is null, but that probably would not be worth the effort.
The issue is that the ??= operator assigns to the left if it is null. Expanded, it would look something like this:
a ??= b;
// Equivalent to:
if (a == null) {
a = b;
}
Which is not something that you're trying to achieve. AFAIK, there is no such operator yet in Dart. However, you can try this:
final possiblyNullValue = '';
final myMap = <String, String>{};
myMap['key'] = possiblyNullValue ?? myMap['key'];
// Equivalent to:
if (possiblyNullValue != null) {
myMap['key'] = possiblyNullValue;
}
// or:
myMap['key'] = possiblyNullValue != null? possiblyNullValue : myMap['key'];
Which would work in your case as a one-liner.
You could create your map with all entries, even null, and then filter the null values out:
void main() {
try {
final myMap = <String, dynamic>{
'field1': DummyClass.getString('hello'),
'field2': DummyClass.getString('good'),
'field3': DummyClass.getOptionalString('goodbye'),
'field4': DummyClass.getOptionalString('go'),
}..removeWhere((k, v) => v == null);
print(myMap);
} catch (e) {
print('error condition, $e');
}
}

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.

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

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
}

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);
}

getmethod(methodname,new[]Type) in Type arrays contains ref parameter and method is overrided

For example
class xx
{
public string name
{
get {return "";}
}
}
class yy
{
public string name(string n)
{
return "";
}
public string name(string n,ref string m)
{
return "";
}
public string name(string n,string m,ref xx k)
{
return "";
}
}
How to get "name" method by reflection technology ?
There's no easy way to do it using GetMethod. However, you can easily do it with GetMethods and Linq :
var methodInfo = from m in typeof(yy).GetMethods()
where m.Name == "name"
let prms = m.GetParameters()
where prms.Length == 3
&& prms[0].ParameterType == typeof(string)
&& prms[1].ParameterType == typeof(string)
&& prms[2].ParameterType == typeof(xx).MakeByRefType()
select m;
You could use Type.MakeByRefType()-Method to create an ref type param. The rest is done by reflection classes.
var method = typeof(yy).GetMethod(
"name",
new[] {typeof(string), typeof(string).MakeByRefType()});