I could done like this but I think there should be a way to do this better;
Resource.ResourceIncrease resource = new Resource.ResourceIncrease();
using (IDbConnection connection = OpenConnection())
{
dynamic reader = connection.Query<dynamic>("UserResourceGet", new { UserId = UserId }, commandType: CommandType.StoredProcedure).SingleOrDefault();
resource.Wood.value = reader.Wood;
resource.Wood.increase = reader.WoodIncome;
resource.Food.value = reader.Food;
resource.Food.increase = reader.FoodIncome;
resource.Stone.value = reader.Stone;
resource.Stone.increase = reader.StoneIncome;
resource.Gold.value = reader.Gold;
resource.Gold.increase = reader.GoldIncome;
}
return resource;
SQL SP >
SELECT Wood, Food, Stone, Gold, WoodIncome, FoodIncome, StoneIncome, GoldIncome
FROM Resources WHERE UserId = #UserId
Class >
public class Resource
{
public int Wood { get; set; }
public int Food { get; set; }
public int Stone { get; set; }
public int Gold { get; set; }
}
public class ResourceIncrease
{
public Increase Wood{ get; set; }
public Increase Food { get; set; }
public Increase Stone { get; set; }
public Increase Gold { get; set; }
public ResourceIncrease()
{
this.Wood = new Increase();
this.Food = new Increase();
this.Stone = new Increase();
this.Gold = new Increase();
}
}
public class Increase
{
public int value { get; set; }
public int increase { get; set; }
}
I would create a class that match the return of the SP, and then would use AutoMapper (http://automapper.org/) to map that class to the ResourceIncrease class.
Check this
http://geekswithblogs.net/EltonStoneman/archive/2012/01/03/mapping-and-auto-mapping-objects.aspx
Related
I have an AcadamicFee list, at one point in time I want to insert an item under Fee. So that, it should add like Fee[1], Fee[2].modified the code like below.
I want to insert one new item under Fee list. But it didn't reflect. How to update the AcadamicFee list through Linq?
Thanks in advance.
AcadamicFee[0]
{
----
----
----
TermDetails [0]
{
---
Fee[0]
Fee[1]
Fee[2]
}
}
public class Fee
{
public int FeeID { get; set; }
public string FeeName { get; set; }
public string FeeAmount { get; set; }
public string IsFineApplicable { get; set; }
public string LastDate { get; set; }
}
public class Ter
{
public int TermID { get; set; }
public string TermName { get; set; }
public IEnumerable<Fee> FeeDetails { get; set; }
}
public class AcadamicFee
{
public int id { get; set; }
public string AdmissionID { get; set; }
public string StudentName { get; set; }
public int Class { get; set; }
public string AcadamicYear { get; set; }
public Nullable<int> TotalPaid { get; set; }
public Nullable<int> AcadamicAmount { get; set; }
public Nullable<int> BalanceAmount { get; set; }
public IEnumerable<Term> TermDetails { get; set; }
}
Any clue how to do with Linq? I tried something like this:
for (var i = 0; i < fees.Count; i++)
{
bool termDetailsExist = acadamic_fee.Any(a => a.TermDetails.Any(b => b.TermID == fees[i].TermID));
if (termDetailsExist)
{
foreach (AcadamicFeeModel acm in acadamic_fee)
{
foreach (TermModel trm in acm.TermDetails)
{
if (trm.TermID == fees[i].TermID)
{
List<FeeModel> FeeType = new List<FeeModel>();
FeeType.Add(new FeeModel
{
FeeID = fees[i].FeeID,
FeeName = fees[i].FeeName,
FeeAmount = fees[i].FeeAmount,
IsFineApplicable = fees[i].IsFineApplicable,
LastDate = fees[i].LastDate,
});
trm.FeeDetails.ToList().AddRange(FeeType);
}
}
}
}
}
trm.FeeDetails.ToList().AddRange(FeeType);
You've created a new List<FeeModel>, added a copy of the FeeDetails sequence, added a new FeeModel object, and then thrown the new list away.
You need to store the modified list in the property - for example:
foreach (TermModel trm in acm.TermDetails)
{
if (trm.TermID == fees[i].TermID)
{
List<FeeModel> FeeType = new List<FeeModel>();
FeeType.Add(new FeeModel
{
FeeID = fees[i].FeeID,
FeeName = fees[i].FeeName,
FeeAmount = fees[i].FeeAmount,
IsFineApplicable = fees[i].IsFineApplicable,
LastDate = fees[i].LastDate,
});
FeeType.AddRange(trm.FeeDetails);
trm.FeeDetails = FeeType;
}
}
I have the following classes inside my c# console application:-
public class SearchCriteria
{
public string field { get; set; }
public string condition { get; set; }
public string value { get; set; }
public string logical_operator { get; set; }
}
public class ListInfo
{
public int row_count { get; set; }
public int start_index { get; set; }
public string sort_field { get; set; }
public string sort_order { get; set; }
public bool get_total_count { get; set; }
public List<SearchCriteria> search_criteria { get; set; }
}
public class Root
{
public ListInfo list_info { get; set; }
}
and when i tried to populate the Root object, as follow:-
Root root = new Root(){};
root.list_info = new ListInfo();
root.list_info.row_count = 1000;
root.list_info.start_index = 1;
root.list_info.sort_field="subject";
root.list_info.sort_order = "asc";
root.list_info.get_total_count = true;
root.list_info.search_criteria = new List<SearchCriteria>();
root.list_info.search_criteria[0].field = "last_updated_time";
root.list_info.search_criteria[0].condition = "between";
root.list_info.search_criteria[0].value = "$(last_30_days)";
root.list_info.search_criteria[1].field = config.GetSection("ServiceDesk").GetSection("field").Value;
root.list_info.search_criteria[1].condition = "is";
root.list_info.search_criteria[1].value = "yes";
root.list_info.search_criteria[1].logical_operator = "AND";
i got this error:-
Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')"
on root.list_info.search_criteria[0].field = "last_updated_time";.. any advice?
You root.list_info.search_criteria still empty, so there isn't items in this list.
You only should make
root.list_info.search_criteria.Add(new SearchCriteria());
Then it will works.
This question is very similar to this one. That question asks if it's worth the trouble to create classes to deal with an api xml response. My question is the opposite: is it worth it to create classes to build an api request vs simply hard-coding the xml?
This is an example of the latter:
string browseService = "http://Mydomain/SearchSvc/CVWebService.svc/DoBrowse";
var browseRequest = string.Format("<databrowse_BrowseRequest opType=\"{0}\">" +
"<entity clientName=\"{1}\" applicationId=\"{2}\" clientId=\"{3}\" subclientId=\"{4}\" backupsetId=\"{5}\" instanceId=\"{6}\"/>" +
"<paths path=\"{7}\"/><options showDeletedFiles=\"1\" restoreIndex=\"1\"/><mode mode=\"2\"/><queries type=\"1\" queryId=\"countQuery\">" +
"<aggrParam aggrType=\"4\" field=\"0\"/></queries><queries type=\"0\" queryId=\"dataQuery\">" +
"<dataParam><paging firstNode=\"0\" skipNode=\"0\" pageSize=\"15\"/><sortParam ascending=\"1\">" +
"<sortBy val=\"38\"/><sortBy val=\"0\"/></sortParam></dataParam></queries></databrowse_BrowseRequest>",
"2", "testServer123", "29", "1234", "5678", "9123", "1", "/tmp/somefile.txt");
if (browseClientResp.StatusCode == HttpStatusCode.OK)
{
XmlDocument xmlDoc = new XmlDocument();
var test = browseClientResp.GetResponseStream();
xmlDoc.Load(test);
}
And here is an example of the classes I created for the former case:
[XmlRoot("databrowse_BrowseRequest")]
public class CommVaultBrowse
{
[XmlAttribute("opType")]
public int OpType { get; set; }
[XmlElement("session")]
public Session Session { get; set; }
[XmlElement("entity")]
public Entity Entity { get; set; }
[XmlElement("paths")]
public List<Paths> Paths { get; set; }
[XmlElement("timeRange")]
public TimeRange TimeRange { get; set; }
[XmlElement("options")]
public Options Options { get; set; }
[XmlElement("mode")]
public Mode Mode { get; set; }
[XmlElement("queries")]
public List<Queries> Queries { get; set; }
}
public class Session
{
[XmlAttribute("sessionId")]
public int SessionId { get; set; }
}
public class Entity
{
[XmlAttribute("clientName")]
public string ClientName { get; set; }
[XmlAttribute("applicationId")]
public int ApplicationId { get; set; }
[XmlAttribute("clientId")]
public int ClientId { get; set; }
[XmlAttribute("subclientId")]
public string SubclientId { get; set; }
[XmlAttribute("backupSetId")]
public int BackupSetId { get; set; }
[XmlAttribute("instanceId")]
public int InstanceId { get; set; }
}
public class Paths
{
[XmlAttribute("path")]
public string Path { get; set; }
}
public class TimeRange
{
[XmlAttribute("toTime")]
public int ToTime { get; set; }
[XmlAttribute("fromTime")]
public int FromTime { get; set; }
}
public class Options
{
[XmlAttribute("showDeletedFiles")]
public byte ShowDeletedFiles { get; set; }
[XmlAttribute("restoreIndex")]
public byte RestroeIndex { get; set; }
}
public class Mode
{
//the only valid value according to Commvault documentation is 2
[XmlAttribute("mode")]
public int ModeId { get; set; }
}
public class Queries
{
[XmlAttribute("type")]
public int Type { get; set; }
[XmlAttribute("queryId")]
public int QueryId { get; set; }
[XmlElement("aggrParam")]
public AggregateParams AggrParam { get; set; }
[XmlElement("dataParam")]
public DataParams DataParam { get; set; }
}
public class AggregateParams
{
[XmlAttribute("aggrType")]
public int AggrType { get; set; }
[XmlAttribute("field")]
public int Field { get; set; }
}
public class DataParams
{
[XmlElement("paging")]
public Paging Paging { get; set; }
[XmlElement("sortParam")]
public SortParam SortParam { get; set; }
}
public class Paging
{
[XmlAttribute("firstNode")]
public int FirstNode { get; set; }
[XmlAttribute("skipNode")]
public int SkipNode { get; set; }
[XmlAttribute("pageSize")]
public int PageSize { get; set; }
}
public class SortParam
{
[XmlAttribute("ascending")]
public int Ascending { get; set; }
[XmlElement("sortBy")]
public List<SortBy> SortBys { get; set; }
}
public class SortBy
{
[XmlAttribute("val")]
public int Val { get; set; }
}
I realized after the fact that instantiating an object of type CommVaultBrowse could get kinda complicated:
var test = new CommVaultBrowse
{
OpType = 2,
Session = new Session
{
SessionId = 1234
},
Entity = new Entity
{
ApplicationId = 29,
BackupSetId = 222,
ClientId = 333,
ClientName = "testServer123",
InstanceId = 1,
SubclientId = "subclient1"
},
Paths = new List<Paths>
{
new Paths
{
Path = "\\C:\\Users\\Administrator\\Desktop\\"
}
},
TimeRange = new TimeRange
{
FromTime = 1378180800,
ToTime = 1378439999
},
Options = new Options
{
RestroeIndex = 1,
ShowDeletedFiles = 0
},
Mode = new Mode
{
ModeId = 2
},
Queries = new List<Queries>
{
new Queries
{
Type = 0, QueryId = 1,
AggrParam = new AggregateParams
{
AggrType = 0,
Field = 1
}
},
new Queries
{
Type = 0,
QueryId = 1,
DataParam = new DataParams
{
Paging = new Paging
{
FirstNode = 1,
PageSize = 20,
SkipNode = 0
},
SortParam = new SortParam
{
Ascending = 1,
SortBys = new List<SortBy>
{
new SortBy
{
Val = 1
},
new SortBy
{
Val = 2
}
}
}
}
}
}
};
Is there a standard way of building these types of requests?
Build an XSD file that would allow you to validate your xml.
Then used XSD.exe to create the classes that would serialize into your xml.
https://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx
Serialize an object to string
I have been searching for days now trying to figure this one out. It saves my records correctly but throws the following error:
The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: Unable to set field/property Actors on entity type BOR.DataModel.StagComplaint. See InnerException for details.
I am using Code First and EF 5 in a C# Web Forms solution with a supporting WCF Service. Here are my POCO classes:
public partial class StagComplaint : ComplaintBase {
public IList<StagParcel> Parcels { get; set; }
public IList<StagActor> Actors { get; set; }
public IList<StagRectification> Rectifications { get; set; }
public ComplaintType ComplaintType { get; set; }
public int ComplaintTypeID { get; set; }
public StagComplaint() {
this.Parcels = new List<StagParcel>();
this.Actors = new List<StagActor>();
this.Rectifications = new List<StagRectification>();
}
}
public class ComplaintBase : BORBase {
public string Number { get; set; }
public int ParentID { get; set; }
public int TaxYear { get; set; }
public string Category { get; set; }
public double BuildingValue { get; set; }
public double LandValue { get; set; }
public double OwnerOpinion { get; set; }
public string Notes { get; set; }
}
public class BORBase {
[Required]
public DateTime CreationDate { get; set; }
public int ID { get; set; }
[MaxLength(25)]
[Required]
public string UserIdentification { get; set; }
}
public partial class StagParcel : ParcelBase {
public virtual StagActor Owner { get; set; }
[ForeignKey("Owner")]
public int OwnerID { get; set; }
public StagAddress Address { get; set; }
[IgnoreDataMember]
public virtual StagComplaint Complaint { get; set; }
public int ComplaintID { get; set; }
public StagParcel() {
this.Address = new StagAddress();
}
}
public class ParcelBase : BORBase {
public string Number { get; set; }
public double BuildingValue { get; set; }
public double LandValue { get; set; }
public double OwnerOpinion { get; set; }
public string LandUseCode { get; set; }
public string NeighborhoodCode { get; set; }
public string TaxDistrict { get; set; }
public string SchoolDistrict { get; set; }
public int SchoolBoardID { get; set; }
}
public partial class StagActor : ActorBase {
public StagAddress Address { get; set; }
public virtual IList<StagEmail> Emails { get; set; }
public virtual IList<StagPhone> Phones { get; set; }
[IgnoreDataMember]
public virtual StagComplaint Complaint { get; set; }
public int ComplaintID { get; set; }
public virtual Role Role { get; set; }
public int RoleID { get; set; }
public StagActor() {
this.Emails = new List<StagEmail>();
this.Phones = new List<StagPhone>();
this.Address = new StagAddress();
}
}
public class ActorBase : BORBase {
public string Name { get; set; }
}
public class StagRectification : BORBase {
public bool Active { get; set; }
public string Notes { get; set; }
public virtual RectificationType RectificationType { get; set; }
public int RectificationTypeID { get; set; }
[IgnoreDataMember]
public virtual StagComplaint Complaint { get; set; }
public int ComplaintID { get; set; }
}
This is the client side code I am using to create the Complaint:
public int AddParcelsToStagingComplaint(List<string> parcelIDs, string userID) {
StagComplaint comp = new StagComplaint();
int Result = 0;
using (BORServiceClient db = new BORServiceClient()) {
comp = new StagComplaint() {
BuildingValue = 111222,
Category = "*",
LandValue = 222333,
Number = "*",
TaxYear = DateTime.Now.Year,
ComplaintTypeID = 1,
UserIdentification = userID,
CreationDate = DateTime.Now,
};
StagAddress ca = new StagAddress() { Line1 = "670 Harvard Blvd", City = "Cleveland", State = "OH", ZipCode = "44113", };
List<StagPhone> ps = new List<StagPhone>();
ps.Add(new StagPhone() { Number = "5556664646", Type = PhoneTypes.Home, UserIdentification = userID, CreationDate = DateTime.Now, });
comp.Actors.Add(
new StagActor() {
Name = "Joe Schmoe",
Address = ca,
Phones = ps,
RoleID = 1,
UserIdentification = userID,
CreationDate = DateTime.Now,
}
);
StagAddress aa = new StagAddress() {
City = wp.Address.City,
Line1 = wp.Address.Line1,
Line2 = wp.Address.Line2,
State = wp.Address.State,
ZipCode = wp.Address.ZipCode,
};
ps = new List<StagPhone>();
ps.Add(new StagPhone() { Number = "4448887878", Type = PhoneTypes.Work, UserIdentification = userID, CreationDate = DateTime.Now, });
StagParcel p = new StagParcel() {
Address = new StagAddress() { Line1 = "4 Oxford Drive", City = "Hudson", State = "OH", ZipCode = "44236" },
BuildingValue = wp.BuildingValue,
LandUseCode = wp.LandUseCode,
LandValue = wp.LandValue,
NeighborhoodCode = wp.NeighborhoodCode,
Number = wp.Number,
Owner = new StagActor() { Name = "Owner Person", Address = aa, RoleID = 2, Phones = ps, UserIdentification = userID, CreationDate = DateTime.Now, },
OwnerOpinion = wp.OwnerOpinion,
SchoolBoardID = wp.SchoolBoardID,
SchoolDistrict = wp.SchoolDistrict,
TaxDistrict = wp.TaxDistrict,
UserIdentification = userID,
CreationDate = DateTime.Now,
};
comp.Parcels.Add(p);
ServiceResponse<int> saved = db.AddComplaint((ComplaintBase)comp, Contexts.Staging, userID);
if (saved.WasSuccessful)
Result = saved.Result;
} // using the database
return Result;
} // AddParcelsToStagingComplaint - Method
Here is the WCF method that gets called:
using (StagComplaintRepo cr = new StagComplaintRepo()) {
cr.Add((StagComplaint)complaint, userID);
if (cr.Save()) {
Result.Result = complaint.ID;
Result.WasSuccessful = true;
} else {
Result.AddException(string.Format("Unable to create a new Complaint in the {0} context.", context));
} // if the save was successful
} // using the Complaint Repository
And here is the BaseRepository that has the Save and Add methods:
public abstract class BaseRepository<T> : IDisposable, IRepository<T> where T : class {
public virtual bool Save(bool detectChanges = false) {
if (detectChanges == true)
this.Entities.ChangeTracker.DetectChanges();
return (this.Entities.SaveChanges() > 0);
}
public virtual void Add(T entity, string userID) {
this.Entities.Set<T>().Add(entity);
}
...
}
It fails on the above this.Entities.SaveChanges() call with the error mentioned at the top of this post. There is no extra inner exception. If I only fill in the Complaint properties that are required and are part of that object, it works. But once I add a Parcel with an Actor it fails.
I assume it is something simple, perhaps a switch needs to be turned on or off. But similar errors all seem to reference AcceptChanges and that is not the issue here. At least based on the error message. Any help would be appreciated.
EDIT
Here is the full stack trace:
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at BOR.WebService.Repositories.BaseRepository`1.Save(Boolean detectChanges) in d:\DevProjects\BOR\WebService\Main\Source\WebServiceSolution\WcfServiceProject\Repositories\BaseRepository.cs:line 22
at BOR.WebService.BORService.AddComplaint(ComplaintBase complaint, Contexts context, String userID) in d:\DevProjects\BOR\WebService\Main\Source\WebServiceSolution\WcfServiceProject\BORService.svc.cs:line 65
Line 22 is:
return (this.Entities.SaveChanges() > 0);
Line 65 is:
if (cr.Save()) {
I'm using EF4.1 code first to create a simple database app with SQL CE 4 backend. I have a Product class and a CallItem class defined as so:
class CallItem
{
public int id { get; set; }
public float discount { get; set; }
public virtual Product Product { get; set; }
}
class Product
{
public int id { get; set; }
public decimal BaseCost { get; set; }
public int UnitSize { get; set; }
public bool isWasteOil { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Ingredients { get; set; }
}
edit - When I am creating a collection of CallItems using a LINQ query, I cannot access the attributes of the Product attached to each CallItem, eg
var callItems = from ci in context.CallItems select ci;
foreach(CallItem callItem in callItems)
{
RunSheet nrs = new RunSheet();
nrs.prodCode = callitem.Product.Code;
}
Interrogating the database shows that Productid in CallItems is being populated. However, the following line generates a NullReferenceException during run time:
nrs.prodCode = callitem.Product.Code;
Because callitem.Product is evaluating to null. Is this something to do with lazy loading and if so how can I resolve the issue?
RunSheet is another class, nrs is an instance whose attribute 'prodCode' I want to populate with the CallItem's Product's code.
Thanks!
From that code what you've showed it should work. Have you tried explicit loading?
var callItems = from ci in context.CallItems.Include(c => c.Product) select ci;
foreach(CallItem callItem in callItems)
{
RunSheet nrs = new RunSheet();
nrs.prodCode = callitem.Product.Code;
}
public class CallItem
{
public int Id { get; set; }
public float Discount { get; set; }
public virtual Product Product { get; set; }
}
public class Product
{
public int Id { get; set; }
public decimal BaseCost { get; set; }
public int UnitSize { get; set; }
public bool IsWasteOil { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Ingredients { get; set; }
}
using (var context = new StackOverFlowContext())
{
var p = new Product
{
Id = 1,
BaseCost = 200,
Code = "Hola",
Description = "Soe description",
Ingredients = "Some ingredients",
IsWasteOil = true,
Name = "My Product",
UnitSize = 10
};
var item = new CallItem
{
Id = 101,
Discount = 10,
Product = p
};
context.CallItems.Add(item);
context.SaveChanges();
var result = from temp in context.CallItems
select temp;
Console.WriteLine("CallItem Id"+result.First().Id);
Console.WriteLine("ProductId"+result.First().Product.Id);
}
I wrote the above code with the following output
CallItemId 1
ProductId 1
The sql Profiler showed this
SELECT TOP (1)
[c].[Id] AS [Id],
[c].[Discount] AS [Discount],
[c].[Product_Id] AS [Product_Id]
FROM [dbo].[CallItems] AS [c]
It was too long for a comment ,so i put it here .