I'm using MVC C# and entity frame work.
So in my partial view I want to change data.
This is my controller
public ActionResult BusinessDetails(){
int bsId = bskey ?? default(int);
var BusinessQuery = GetBusinessById(bsId);
var PeopleQuery = BusinessQuery.t_PEOPLE
.Where(p => p.PP_IS_CONTACT == true).AsEnumerable();
var peopleCollection = new EntityCollection<t_PEOPLE>();
foreach (var m in PeopleQuery)
{
//This is problem.-----------
peopleCollection.Add(m);
} //--------------
BusinessQuery.t_PEOPLE = peopleCollection;
return PartialView("_EditBusiness", BusinessQuery);
}
return RedirectToAction("Index");
}
public t_BUSINESS GetBusinessById(int id){
if (id == 0)
return null;
var query = from b in db.t_BUSINESS
where b.BS_KEY == id
select b;
var Business = query.FirstOrDefault();
return Business;
}
So how can I assign the PeopleQuery to my BusinessQuery.t_PEOPLE.
Ther is error and says
The object could not be added to the EntityCollection or EntityReference. An object that is attached to an ObjectContext cannot be added to an EntityCollection or EntityReference that is not associated with a source object
You could directly query the records you are looking for:
public ActionResult BusinessDetails()
{
int bsId = bskey ?? default(int);
var business = GetContactBusinessById(bsId);
return PartialView("_EditBusiness", business);
}
public t_BUSINESS GetContactBusinessById(int id)
{
if (id == 0)
{
return null;
}
var query =
from b in db.t_BUSINESS
from p in b.t_PEOPLE
where b.BS_KEY == id && p.PP_IS_CONTACT
select b;
return query.FirstOrDefault();
}
try this
var PeopleQuery = BusinessQuery.t_PEOPLE.Where(p => p.PP_IS_CONTACT == true).ToList();
Related
public ServiceResponce Write(Guid senderID, Guid reciverID, string body)
{
Message message = new Message
{
Body = body
};
var reciver = context.Users.Where(c => c.Id == reciverID).Single();
var sender = context.Users.Where(c => c.Id == senderID).Single();
message.Sender = sender;
message.Reciver = reciver;
context.SaveChanges();
return new ServiceResponce();
}
I got exeption of empty sequence . I am geting Guid id resulsts from HTTPContext.Users.FindFirstValue(ClaimTypes.NameIdentifier)
and I am geting results it is not null.
I cant solve this problem.
Caller method :
public IActionResult Wright(Guid reciverID,string body)
{
var userID = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
var neededID = Guid.Parse(userID);
_chatService.Write(neededID, reciverID, body);
return Ok();
}
Try this:
public ServiceResponce Write(...)
{
...
var reciver = context.Users.Where(c => c.Id == reciverID).SingleOrDefault();
var sender = context.Users.Where(c => c.Id == senderID).SingleOrDefault();
if(reciver == null || sender ==null)
{
//Log??
return null;
}
...
}
public IActionResult Wright(Guid reciverID,string body)
{
var userID = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
// If you really want to put the validation logic here
Guid neededID;
if (!Guid.TryParse(userId, out var neededID))
{
//Log?
return BadRequest();
}
if(_chatService.Write(neededID, reciverID, body) == null)
return BadRequest();
return Ok();
}
I have a product list query that I wrote under normal conditions. I have created a mapper for this query and I can use it as follows.
public IActionResult Index()
{
// use normal selecting
var productList = _context.Products.Select(s => new ProductDto
{
Id = s.Id,
CreateTime = s.CreateTime,
Title = s.Title,
Description = s.Description
}).ToList();
// use my mapper
var productListMap = _context.Products
.ToMap<Product, ProductDto>().ToList();
return View();
}
On simple data types it works just fine as long as the type and name are the same. But it cannot convert complex types (classes and models).
I thought it would be a nice idea to specify it as a parameter at the time of writing, so that it gets the job done. So I want a layout like below.
public IActionResult Index()
{
// what i'm doing now
var productList = _context.Products.Select(s => new ProductDto
{
Id = s.Id,
CreateTime = s.CreateTime,
Title = s.Title,
Description = s.Description,
Features = s.Features.ToMap<Feature, FeatureDto>().ToList(),
Images = s.Images.ToMap<Image, ImageDto>().ToList()
}).ToList();
// i want to do
var productListMap = _context.Products
.ToMap<Product, ProductDto>(p => p.Features, p.Images).ToList();
return View();
}
What do I need to change/add in the mapper class below to make it easy to use this way?
public static class Mapper
{
public static IEnumerable<TDestination> ToMap<TSource, TDestination>(this IEnumerable<TSource> sourceList)
{
return sourceList.Select(source => source.ToMap<TSource, TDestination>());
}
public static TDestination ToMap<TSource, TDestination>(this TSource source)
{
if (source == null) return default;
var entityProperties = source.GetType().GetProperties();
var dtoInstance = Activator.CreateInstance<TDestination>();
for (int i = 0; i < entityProperties.Length; i++)
{
var currentPropertyName = entityProperties[i].Name;
var value = GetPropertyValue(source, currentPropertyName);
if (dtoInstance.GetType().GetProperty(currentPropertyName) == null)
continue;
try { dtoInstance.GetType().GetProperty(currentPropertyName).SetValue(dtoInstance, value); }
catch (Exception ex) { /* Nothing */ }
}
return dtoInstance;
}
public static object GetPropertyValue(object source, string propName)
{
if (source == null) throw new ArgumentException("Value cannot be null.", nameof(source));
if (propName == null) throw new ArgumentException("Value cannot be null.", nameof(propName));
var prop = source.GetType().GetProperty(propName);
return prop != null ? prop.GetValue(source, null) : null;
}
}
I'm trying to validate an entity coming from an External context has not changed.
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
I have a method which takes in an entity which has not been loaded from the context.
public bool Validate(Employee employee)
{
using (var context = new Context())
{
return context.Entry(employee).State == EntityState.Modified;
}
}
I would like to attach and verify that the attached entity is not modified from whats in the database.
I would prefer not to manually have to iterate of the properties. Is there a way to hack around this?
No need to attach the external entity. You can use the external entity to set values of the database entity and then check the state of the latter:
public bool Validate(Employee externalEmployee)
{
using var context = new Context(); // C# 8.0
var dbEntity = context.Where(x => x.Id == externalEmployee.Id).SingleOrDefault();
if (dbEntity != null)
{
context.Entry(dbEntity).CurrentValues.SetValues(externalEmployee);
return context.Entry(dbEntity).State == EntityState.Modified;
}
return false; // Or true, depending on your semantics.
}
You can try:
public static List<string> GetChanges<T>(this T obj, T dbObj)
{
List<string> result = new List<string>();
var type = typeof(T);
foreach (var prop in type.GetProperties())
{
var newValue = prop.GetValue(obj, null);
var dbValue = prop.GetValue(dbObj, null);
if(newValue == null && dbValue != null)
{
result.Add(prop.Name);
continue;
}
if (newValue != null && dbValue == null)
{
result.Add(prop.Name);
continue;
}
if (newValue == null && dbValue == null)
continue;
if (!newValue.ToString().Equals(dbValue.ToString()))
result.Add(prop.Name);
}
return result;
}
if resultList.Count > 0, your object has changes.
In your Validate Method:
public bool Validate(Employee employee)
{
using (var context = new Context())
{
Employee dbEmployee = context.Employee.Find(employee.Id);
if(employee.GetChanges(dbEmployee).Count > 0)
return true;
return false;
}
}
It's a god workaround =D
Works for me!
i want to show large data in kendo grid using skip and take solution for server paging and filtering. my controller and method is :
public ActionResult LoadStudents(int page, int pageSize, int take, bool? activeOnly)
{
var sorterCollection = KendoGridSorterCollection.BuildCollection(Request);
var filterCollection = KendoGridFilterCollection.BuildCollection(Request);
...
LogUI.Data.kiwiEntities en = new Data.kiwiEntities();
var result = en.Syslogds.Where(s => el.Contains(s.MsgHostAddress)
&& op.Contains(s.MsgCustom04.Trim()));
var filteredStudents = result.MultipleFilter(filterCollection.Filters);
int coun = filteredStudents.Count();
var pagedData = filteredStudents.OrderBy(t => t.MsgDateTime).Skip((page-1) * pageSize).Take(pageSize);
var pagedDataList = pagedData.ToList();
var jsonData = new { total = coun, pagedDataList };
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
and my MultipleFilter Method is :
public static IQueryable<T> MultipleFilter<T>(this IQueryable<T> data,
List<KendoGridFilter> filterExpressions)
{
if ((filterExpressions == null) || (filterExpressions.Count <= 0))
{
return data;
}
IQueryable<T> filteredquery = from item in data select item;
for (int i = 0; i < filterExpressions.Count; i++ )
{
var index = i;
Func<T, bool> expression = item =>
{
var filter = filterExpressions[index];
var itemValue = item.GetType()
.GetProperty(filter.Field)
.GetValue(item, null);
if (itemValue == null)
{
return false;
}
var value = filter.Value;
switch (filter.Operator)
{
case "eq":
return itemValue.ToString() == value;
case "startswith":
return itemValue.ToString().StartsWith(value);
case "contains":
return itemValue.ToString().Contains(value);
case "endswith":
return itemValue.ToString().EndsWith(value);
}
return true;
};
filteredquery = filteredquery.Where(expression).AsQueryable();
}
return filteredquery;
}
every things are ok but when i use filter in my kendo grid i have a out of memory exception in filteredStudents variable.
Here you can find an example on Kendo UI forum.
Below is an example from that page so you can get an idea how the method works:
public ActionResult Products_Read([DataSourceRequest]DataSourceRequest request)
{
using (var northwind = new NorthwindEntities())
{
IQueryable<Product> products = northwind.Products;
//Convert the Product entities to ProductViewModel instances.
DataSourceResult result = products.ToDataSourceResult(request, product => new ProductViewModel
{
ProductID = product.ProductID,
ProductName = product.ProductName,
UnitsInStock = product.UnitsInStock
});
return Json(result);
}
}
I have list with items and I check if an item exists in a List. If it exists, I try to find it.
I think that it has a little overhead, because I currently make two passes over the list. Is it possible to do in single pass?
Currently I have.
public partial class Item
{
public string text;
public int id;
}
....
static List<Item> data = new List<Item>();
static stub = new Item() { text = "NaN", id = -1 };
public static Item Get(int targetId)
{
if (data.Any(f => f.id == targetId) == false)
{
return stub;
}
return data.Find(f => f.id == targetId);
}
I want something like
...
public static Item Get(int targetId)
{
Item result;
result = data.Find(f => f.id == targetId);
if (result == null)
{
return stub;
}
return result;
}
You seem to be looking for FirstOrDefault():
Item _stub = new Item
{
text = "NaN",
id = -1
};
public Item FindByID(int id)
{
// Find the first item that has the provided id, or null if none exist.
var existingItem = data.FirstOrDefault(i => i.id == id);
// When not found, return the _stub
return existingItem ?? _stub;
}
You also may want to reconsider your naming conventions and whether you actually need these members to be static.
You can use List.FindIndex:
public static Item get(int i)
{
int index = data.FindIndex(item => item.id == i);
if (index == -1) return stub;
return data[index];
}
If it's actually an array you can use Array.FindIndex:
public static Item get(int i)
{
int index = Array.FindIndex(data, item => item.id == i);
if (index == -1) return stub;
return data[index];
}
So FirstOrDefault() is the way to go. You can also use SingleOrDefault() if there is only supposed to be one item in that list.
static stub = new Item() { text = "NaN", id = -1 };
public static Item get(int i)
{
Item result;
result = data.FirstOrDefault(f => f.id == i);
if (result == null)
{
return stub;
}
return result;
}
I use an extension method for exactly this purpose
public static T FirstOrSpecificDefault<T>(this IEnumerable<T> list,
Func<T, bool> predicate, T defaultValue)
{
return list.FirstOrDefault(predicate) ?? defaultValue;
}
usage in your case would be
Item result = list.FirstOrSpecificDefault(f => f.id == i, stub);
I think you can try this:
return data.Find(f => f.id == i) ?? stub;