This my Controller
public JsonResult SaveBillingSystemParameters(BillingSystemParameters model)
{
var id = -1;
//Initialize the newId variable
var userId = Helpers.GetLoggedInUserId();
var currentDate = Helpers.GetInvariantCultureDateTime();
var defaultCorporateId = Helpers.GetSysAdminCorporateID();
//Check if Model is not null
if (model != null)
{
using (var bal = new BillingSystemParametersBal())
{
model.CorporateId = defaultCorporateId;
if (model.Id > 0)
{
model.ModifiedBy = userId;
model.ModifiedDate = currentDate;
}
else
{
model.CreatedBy = userId;
model.CreatedDate = currentDate;
model.CorporateId = Helpers.GetSysAdminCorporateID();
}
//Call the AddBillingSystemParameters Method to Add / Update current BillingSystemParameters
id = bal.SaveBillingSystemParameters(model);
}
}
return Json(id);
}
//Bal class
public int SaveBillingSystemParameters(BillingSystemParameters model)
{
using (var rep = UnitOfWork.BillingSystemParametersRepository)
{
if (model.Id > 0)
{
var current = rep.GetSingle(model.Id);
model.CreatedBy = current.CreatedBy;
model.CreatedDate = current.CreatedDate;
rep.UpdateEntity(model, model.Id);
}
else
rep.Create(model);
return model.Id;
}
}
I am getting following error
do what exception message says, inspect EntityValidationErrror
this exception usually means you're trying to break some constraint like varchar filed width
if you browse through this param you'll get more details on type of constrain SaveChanges() tried to brake
Related
I am using 2 LiveDatas from separate tables into the repository of my application. I add the two LiveDatas as sources to the CustomMediatorLiveData class which extends MediatorLiveData.
In the onChanged callback of addSource method for each LiveData, I send the values of both the LiveDatas into a method that combines both and returns a single LiveData which is set as the value for the CustomMediatorLiveData object. I am creating an object of this CustomMediatorLiveData in my Repository and passing the two LiveDatas as parameters for the constructor.
This runs and doesn't give any error but it is messing up the data within the LiveData itself.
example: If the date was originally 15th August 2020 then it can be something like 14th August 0001.
CustomMediatorLiveData:
public class CustomMediatorLiveData extends MediatorLiveData<List<Object>> {
private List<Note> notes = Collections.emptyList();
private List<RecurringTask> recurringTasks = Collections.emptyList();
public CustomMediatorLiveData(LiveData<List<Note>> liveNotes, LiveData<List<RecurringTask>> liveRecurringTasks) {
addSource(liveNotes, notes1 -> {
if (notes1 != null) {
this.notes = notes1;
}
setValue(combineData(notes,recurringTasks));
});
addSource(liveRecurringTasks, recurringTasks1 -> {
if (recurringTasks1 != null) {
this.recurringTasks = recurringTasks1;
}
setValue(combineData(notes,recurringTasks));
});
}
// This method adds the 2 lists into one and sorts them based on dates and priority.
private List<Object> combineData(List<Note> notes, List<RecurringTask> recurringTasks) {
List<Object> combinedList = new ArrayList<>();
if (notes != null && !notes.isEmpty())
combinedList.addAll(notes);
if(recurringTasks!=null && !recurringTasks.isEmpty())
combinedList.addAll(recurringTasks);
Collections.sort(combinedList, new Comparator<Object>() {
#Override
public int compare(Object o1, Object o2) {
Date d1, d2;
Note n1 = null, n2 = null;
RecurringTask r1 = null, r2 = null;
if (o1 instanceof Note && o2 instanceof Note) {
int hmm = Boolean.compare(((Note) o2).isPriority(), ((Note) o1).isPriority());
if (hmm != 0)
return hmm;
}
if (o1 instanceof Note) {
d1 = ((Note) o1).getEnd_date();
n1 = ((Note) o1);
} else {
d1 = ((RecurringTask) o1).getEnd_date();
r1 = ((RecurringTask) o1);
}
if (o2 instanceof Note) {
d2 = ((Note) o2).getEnd_date();
n2 = ((Note) o2);
} else {
d2 = ((RecurringTask) o2).getEnd_date();
r2 = ((RecurringTask) o2);
}
if (n1 != null) {
if (r2 != null) {
if (n1.isPriority()) {
return -1;
}
}
}
if (n2 != null) {
if (r1 != null) {
if (n2.isPriority()) {
return 1;
}
}
}
long l1 = d1.getTime() - d2.getTime();
if (l1 > 0) {
return 1;
} else if (l1 < 0) {
return -1;
} else {
return 0;
}
}
});
return combinedList;
}
}
Note Repository class:
public class NoteRepository {
private String DB_NAME = "db_task";
Context context;
private RecurringDao recurringDao;
private LiveData<List<RecurringTask>> upcomingRecurringTasks;
private LiveData<List<Note>> upcomingTasks;
private CustomMediatorLiveData customMediatorLiveData;
private NoteDatabase noteDatabase;
public NoteRepository(Context context) {
noteDatabase = NoteDatabase.getInstance(context);
recurringDao = noteDatabase.recurringDao();
upcomingRecurringTasks = recurringDao.getUpcomingRecurringTask();
upcomingTasks = noteDatabase.daoAccess().fetchUpcomingTasks();
this.context = context;
customMediatorLiveData = new CustomMediatorLiveData(upcomingTasks, upcomingRecurringTasks);
}
public LiveData<List<Object>> getCustomMediatorLiveData() {
return customMediatorLiveData;
}
public LiveData<List<RecurringTask>> getUpcomingRecurringTasks() {
return upcomingRecurringTasks;
}
public LiveData<List<Note>> fetchUpcomingTasks() {
return NoteDatabase.getInstance(context).daoAccess().fetchUpcomingTasks();
}
}
I have tried using the MediatorLiveData object and add the two LiveData sources to it in the repository itself and the same issue persists.
What is the correct way to implement this? How to combine 2 LiveDatas into a single LiveData that can be observed.
I'm refactoring some previously written MVC and Entity Framework code. The way the initial code was written they called a DAL.GetGroupDetail(int groupId) method. In that method it created a ViewModel and populated several properties. Some of those properties are Lists for things like CostCenters, Cities, Groups. I want to break those calls out into their own methods so that they can be re-used in other controllers.
My question is that doing that I'm creating new Contexts using the Using statement. My understanding is that would create multiple connections to the database and thus would slow down the site if multiple users were using it at the same time?
Example, currently this is the basic code:
public ClockGroupViewModel GetClockGroupDetail(int groupId)
{
GroupViewModel cgdv = new GroupViewModel();
using (var ctx = new VTContext())
{
bio_group group = ctx.bio_group.Where(x => x.group_id == groupId).FirstOrDefault();
cgdv.GroupId = group.group_id;
cgdv.GroupName = group.group_name;
cgdv.Cities = ctx.bio_city.ToList();
var clocks = from c in ctx.bio_clock.Where(x => x.group_id == groupId)
select new ClockViewModel
{
ClockID = c.rdr_id.ToString(),
ClockDescription = c.clock_desc,
};
cgdv.ClockList = clocks.ToList();
cgdv.CostCtrList = (from g in ctx.bio_clock_group
from cgc in ctx.bio_clock_group_costctr
where cgc.group_id == g.group_id && g.group_id == groupId
select cgc.cost_ctr).ToList();
}
This how I'm thinking of changing it:
public ClockGroupViewModel GetClockGroupDetail(int groupId)
{
GroupViewModel cgdv = new GroupViewModel();
using (var ctx = new VTContext())
{
bio_group group = ctx.bio_group.Where(x => x.group_id == groupId).FirstOrDefault();
cgdv.GroupId = group.group_id;
cgdv.GroupName = group.group_name;
cgdv.Cities = GetCityList();
cgdv.ClockList = GetClockGroupClockList(group.group_id);
cgdv.CostCtrList = GetGroupCostCenter(group.group_id);
}
}
public List<bio_clock_city> GetCityList()
{
using (var ctx = new VTContext())
{
return ctx.bio_city.ToList();
}
}
public List<ClockViewModel> GetClockGroupClockList(int groupId)
{
using (var ctx = new VTContext())
{
var data = (from c in ctx.bio_clock.Where(x => x.group_id == groupId)
select new ClockViewModel
{
ClockID = c.rdr_id.ToString(),
ClockDescription = c.clock_desc,
}).ToList();
return data;
}
}
public List<string> GetGroupCostCenter(int groupId)
{
using (var ctx = new VTContext())
{
var data = (from g in ctx.bio_clock_group
from cgc in ctx.bio_clock_group_costctr
where cgc.group_id == g.group_id && g.group_id == groupId
select cgc.cost_ctr).ToList();
return data;
}
}
I am evaluating the performance of Microsoft's implementation of Avro, and at first I thought I was getting phenomenal performance until I realized it just wasn't serializing the entire message ;-)
In the following there is a simple hierarchy of messages decorated with [DataContract] (a base and two derived types). All members are decorated with the [DataMember] attribute. I create a serializer from the base message type and serialize a list of derived messages, but it appears to only serialize/deserialize the base class members. All of the derived message members are missing from the result.
Am I missing something? My application will require mixed message types.
FWIW I don't see any strings from the second derived type in the binary file, so I suspect the derived type members aren't being serialized.
Thanks, Greg
class Program
{
[DataContract(Name = "SideType", Namespace = "AvroMessage")]
public enum EventType
{
Unknown = 0,
One = 1,
Two = 2
}
[DataContract(Name = "MessageBase", Namespace = "AvroMessage")]
public class MessageBase
{
[DataMember(Name = "Subtype")]
public string Subtype;
[DataMember(Name = "Timestamp")]
public DateTime Timestamp;
[DataMember(Name = "GroupName")]
public string GroupName;
public override bool Equals(object obj)
{
MessageBase other = obj as MessageBase;
if (other == null) return false;
return Subtype == other.Subtype &&
Timestamp == other.Timestamp &&
GroupName == other.GroupName;
}
}
[DataContract(Name = "SubMessage1", Namespace = "AvroMessage")]
public class SubMessage1 : MessageBase
{
[DataMember(Name = "Volume")]
public int Volume;
[DataMember(Name = "Count")]
public int Count;
[DataMember(Name = "DetectedSide")]
public EventType Event;
public override bool Equals(object obj)
{
SubMessage1 other = obj as SubMessage1;
if (other == null) return false;
return Subtype == other.Subtype &&
Timestamp == other.Timestamp &&
GroupName == other.GroupName &&
Event == other.Event &&
Volume == other.Volume &&
Count == other.Count;
}
}
[DataContract(Name = "SubMessage2", Namespace = "AvroMessage")]
public class SubMessage2 : MessageBase
{
[DataMember(Name = "Name1")]
public string Name1;
[DataMember(Name = "Volume1")]
public int Volume1;
[DataMember(Name = "Name2")]
public string Name2;
[DataMember(Name = "Volume2")]
public int Volume2;
[DataMember(Name = "PriceMove")]
public double PriceMove;
public override bool Equals(object obj)
{
SubMessage2 other = obj as SubMessage2;
if (other == null) return false;
return Subtype == other.Subtype &&
Timestamp == other.Timestamp &&
GroupName == other.GroupName &&
Volume1 == other.Volume1 &&
Name1 == other.Name1 &&
Volume2 == other.Volume2 &&
Name2 == other.Name2 &&
PriceMove == other.PriceMove;
}
}
public class MessageFactory
{
public static IEnumerable<MessageBase> CreateMessages(int number)
{
Random ran = new Random();
List<MessageBase> retval = new List<MessageBase>();
for (int i = 0; i < number; i++)
{
if (ran.Next(2) == 0)
{
SubMessage1 sub1 = new SubMessage1();
sub1.Timestamp = DateTime.Now;
sub1.GroupName = "Group" + DateTime.Now.Millisecond.ToString();
sub1.Subtype = "SubMessag1";
sub1.Volume = ran.Next(10000);
sub1.Count = ran.Next(100);
if (ran.Next(2) == 0)
{
sub1.Event = EventType.One;
}
else
{
sub1.Event = EventType.Two;
}
retval.Add(sub1);
}
else
{
SubMessage2 sub2 = new SubMessage2();
sub2.Timestamp = DateTime.Now;
sub2.GroupName = "Group" + DateTime.Now.Millisecond.ToString();
sub2.Subtype = "SubMessag2";
sub2.Volume1 = ran.Next(1000);
sub2.PriceMove = ran.NextDouble() * 100 - 50;
sub2.Volume2 = ran.Next(1000);
sub2.Name1 = "Contract" + (DateTime.Now.Millisecond + ran.Next(5)).ToString();
sub2.Name2 = "Contract" + DateTime.Now.Millisecond.ToString();
retval.Add(sub2);
}
}
return retval;
}
}
public static void TestAvro(int count)
{
bool correct = false;
long serTicks = 0;
long deserTicks = 0;
Stopwatch sw = new Stopwatch();
sw.Reset();
var serializer = Microsoft.Hadoop.Avro.AvroSerializer.Create<MessageBase>();
MessageBase[] messages = new MessageBase[count];
using (var file = File.Create(#"C:\test_avro.bin"))
{
int i = 0;
foreach (var message in MessageFactory.CreateMessages(count))
{
messages[i++] = message;
sw.Start();
serializer.Serialize(file, message);
sw.Stop();
}
}
serTicks = sw.ElapsedTicks;
sw.Reset();
List<int> badMessages = new List<int>();
using (var file = File.OpenRead(#"C:\test_avro.bin"))
{
for (int i = 0; i < count; i++)
{
sw.Start();
MessageBase message = serializer.Deserialize(file);
sw.Stop();
SubMessage1 m1 = message as SubMessage1;
SubMessage2 m2 = message as SubMessage2;
bool areNull = (m1 == null) && (m2 == null); // Always true
if (!messages[i].Equals(message)) badMessages.Add(i);
}
}
deserTicks = sw.ElapsedTicks;
correct = badMessages.Count == 0;
long size = (new FileInfo(#"C:\test_proto.bin")).Length;
Console.WriteLine(String.Format("Correct: {0}, Time Out: {1}, , Time In: {2}, , Size: {3}", correct, serTicks, deserTicks, size));
}
static void Main(string[] args)
{
TestAvro(10000);
Console.ReadLine();
}
}
My bad - I forgot the KnownType attribute on the base class, one for each derived type. It works if you include the attributes.
In order to create a ViewModel, I tried to call a method GetName() to find the FirstName and LastName for UserID and then add it to the model. But the error tells "Linq to Entities does not recognize the method".
How do I accomplish this in another way?
My code:
public IQueryable<SheetList> GetSheetData()
{
var query = from a in GetSheets()
select new SheetList
{
SheetId = a.ListAllSafetySheets.Id,
SheetTitle = a.ListAllSafetySheets.SafetySheetTitle,
ProductionManagerId = a.ListAllSafetySheets.ProductionManager,
ProductionManagerName = this.GetName(a.ListAllSafetySheets.ProductionManager),
ConstructionManagerId = a.ListAllSafetySheets.ConstructionManager,
Created = a.ListAllSafetySheets.Created,
CreatedBy = a.ListAllSafetySheets.CreatedBy,
UserProfile_UserId = a.ListAllUserProfiles.UserId,
Project_Id = a.ListAllProjects.Id,
ProjectLeaderId = a.ListAllProjects.ProjectLeader,
ConstructionLocation_Id = a.ListAllConstructionLocations.Id,
};
return query;
}
public IQueryable<DataCollection> GetSheets()
{
var query = from vSafety in _db.Sheets
join vUserProfile in _db.UserProfiles
on vSafety.Id
equals vUserProfile.UserId
join vProject in _db.Projects
on vSafety.Id
equals vProject.Id
join vConstructionLocation in _db.ConstructionLocations
on vSafety.Id
equals vConstructionLocation.Id
orderby vSafety.Created descending
select new SafetyAndProjectAndUserAndLocationCollection
{
ListAllSafetySheets = vSafety,
ListAllUserProfiles = vUserProfile,
ListAllProjects = vProject,
ListAllConstructionLocations = vConstructionLocation
};
return query;
}
public string GetName(int? id)
{
string returnValue;
if (id == null)
{
var userModel = _db.UserProfiles.Single(x => x.UserId == id);
string FirstName = userModel.FirstName;
string LastName = userModel.LastName;
returnValue = FirstName + ", " + LastName;
}
else
{
returnValue = "";
}
return returnValue;
}
You'll need to call the method after you build the model. You can try something like this:
public IQueryable<SheetList> GetSheetData()
{
var query = from a in GetSheets()
select new SheetList
{
SheetId = a.ListAllSafetySheets.Id,
SheetTitle = a.ListAllSafetySheets.SafetySheetTitle,
ProductionManagerId = a.ListAllSafetySheets.ProductionManager,
ProductionManagerName = a.ListAllSafetySheets.ProductionManager,
ConstructionManagerId = a.ListAllSafetySheets.ConstructionManager,
Created = a.ListAllSafetySheets.Created,
CreatedBy = a.ListAllSafetySheets.CreatedBy,
UserProfile_UserId = a.ListAllUserProfiles.UserId,
Project_Id = a.ListAllProjects.Id,
ProjectLeaderId = a.ListAllProjects.ProjectLeader,
ConstructionLocation_Id = a.ListAllConstructionLocations.Id,
};
var queryWithNames = query.ToList().ForEach(s => s.ProductionManagerName = this.GetName(s.ProductionManagerName));
return queryWithNames;
}
Since you're having trouble using .ForEach(), you can do this with a regular foreach loop:
foreach(var s in query)
{
s.ProductionManagerName = this.GetName(s.ProductionManagerName);
}
The downside to this is the call to .ToList will enumerate the queryable, executing the query against the database, so if you need to do further filters later outside this method, you may be downloading additional data that you don't need, causing additional overhead.
I have a controller that depends on a Session variable. In order to unit test this controller, I came up with the following solution. It works but I'm wondering if there is a better/cleaner way. Thanks
Controller
public JsonResult UpdateStatus(ImageUpdateStatus imageUpdateStatus, SessionStateItemCollection sessionItems = null)
{
var data = new object();
string status = null;
ImageInfo imageInfo = new ImageInfo();
IImageInfoServices svcImageInfo = new ImageInfoServicesRepository();
imageInfo = svcImageInfo.GetImageByImageId(imageUpdateStatus.ImageId);
IDeviceControlServices svcDevice = new DeviceControlServicesRespository();
IPVSCommandServices svcPVSCmds = new PVSCommandServicesRespository();
if (imageUpdateStatus.Task == "prep")
{
List<UpdateReasonForm> updateReasonForms;
if (sessionItems != null)
{
updateReasonForms = sessionItems["UpdateReasonForms"] as List<UpdateReasonForm>;
}
else
{
updateReasonForms = Session["UpdateReasonForms"] as List<UpdateReasonForm>;
}
foreach (var item in updateReasonForms)
{
if (item.ImageId == imageInfo.ImageId)
{
status = svcPVSCmds.PrepImage(imageInfo, item.NewVersion);
}
}
data = new
{
status
};
}
if (imageUpdateStatus.Task == "boot")
{
status = svcDevice.Boot(imageInfo.ImageId);
data = new
{
status
};
}
return this.Json(data, JsonRequestBehavior.AllowGet);
}
Unit Test
[TestMethod()]
public void UpdateStatusTest()
{
BuildController target = new BuildController(); // TODO: Initialize to an appropriate value
ImageUpdateStatus imageUpdateStatus = new ImageUpdateStatus(); // TODO: Initialize to an appropriate value
imageUpdateStatus.ImageId = 3;
imageUpdateStatus.Task = "prep";
UpdateReasonForm updateReasonForm = new UpdateReasonForm();
updateReasonForm.ImageId = 3;
updateReasonForm.NewVersion = "TestThis";
List<UpdateReasonForm> updateReasonForms = new List<UpdateReasonForm>();
updateReasonForms.Add(updateReasonForm);
var sessionItems = new SessionStateItemCollection();
sessionItems["UpdateReasonForms"] = updateReasonForms;
JsonResult actual;
actual = target.UpdateStatus(imageUpdateStatus, sessionItems);
}
Instead of passing in the session values as a parameter you can mock the session state like here:
How do you mock the session object collection using Moq
You have a dependency on Session. You could move your code into a testable method where you inject the dependency at the method level. It looks like you are on this path I would just abstract the code into its own method allowing you to test the functionality regardless of the whether the data comes from session or not.
public JsonResult UpdateStatusDependencyInjection(ImageUpdateStatus imageUpdateStatus, Dictionary<string, object> sessionValues)
{
var data = new object();
string status = null;
ImageInfo imageInfo = new ImageInfo();
IImageInfoServices svcImageInfo = new ImageInfoServicesRepository();
imageInfo = svcImageInfo.GetImageByImageId(imageUpdateStatus.ImageId);
IDeviceControlServices svcDevice = new DeviceControlServicesRespository();
IPVSCommandServices svcPVSCmds = new PVSCommandServicesRespository();
if (imageUpdateStatus.Task == "prep")
{
List<UpdateReasonForm> updateReasonForms;
if (sessionItems != null)
{
updateReasonForms = sessionItems["UpdateReasonForms"] as List<UpdateReasonForm>;
}
else
{
updateReasonForms = Session["UpdateReasonForms"] as List<UpdateReasonForm>;
}
foreach (var item in updateReasonForms)
{
if (item.ImageId == imageInfo.ImageId)
{
status = svcPVSCmds.PrepImage(imageInfo, item.NewVersion);
}
}
data = new
{
status
};
}
if (imageUpdateStatus.Task == "boot")
{
status = svcDevice.Boot(imageInfo.ImageId);
data = new
{
status
};
}
return this.Json(data, JsonRequestBehavior.AllowGet);
}
http://codingsmith.co.za/a-better-way-of-working-with-httpcontext-session-in-mvc/
This is my implementation of an interface wrapper for Session.
Its currently in production and works fine, its injected into my controllers, but I can use one of the other implementations manually when testing