EF DTO flat view model - c#

I wonder whether there is a shortcut to make a flat view model from entity framework. The user table has a list of addresses. When I populate the view model I use FirstOrDefault for both streetline1 and streetline2. Is there a shortcut to populate the two strings from a list?
static void Main(string[] args)
{
//EF Data
User EFUser = new User();
EFUser.UserId = 1;
EFUser.Username = "Data";
List<Address> ListOfAddress = new List<Address>();
ListOfAddress.Add(new Address() { UserId=1, StreetLine1="address 1",StreetLine2="address line2 1" });
EFUser.Address = ListOfAddress;
ViewModelUserFlat vm = new ViewModelUserFlat();
vm.UserId = EFUser.UserId;
vm.UserName = EFUser.Username;
vm.StreetLine1 = ListOfAddress.Select(a => a.StreetLine1).FirstOrDefault();
vm.StreetLine2 = ListOfAddress.Select(a => a.StreetLine2).FirstOrDefault();
}
class Address
{
public int AddressId { get; set; }
public int UserId { get; set; }
public string StreetLine1 { get; set; }
public string StreetLine2{ get; set; }
}
class User
{
public int UserId { get; set; }
public string Username { get; set; }
public List<Address> Address { get; set; }
}
class ViewModelUserFlat
{
public int UserId { get; set; }
public string UserName { get; set; }
public string StreetLine1 { get; set; }
public string StreetLine2 { get; set; }
}

There are multiple ways to assign StreetLine1 and StreetLine2. As yours Address is a list type you need to use FirstOrDefault or the index
var address = ListOfAddress.FirstOrDefault();
vm.StreetLine1 = address?.StreetLine1;
vm.StreetLine2 = address?.StreetLine2;
vm.StreetLine1 = address.FirstOrDefault().StreetLine1;
vm.StreetLine2 = address.FirstOrDefault().StreetLine2;
vm.StreetLine1 = ListOfAddress[0].StreetLine1;
vm.StreetLine2 = ListOfAddress[0].StreetLine2;

Related

C# Class Initialize and set data and List information

I am able to set the values for each item in ROOT, such as Address_to and Line_items, but when I try to pass the populated class to Post, it's empty.
public class OrdersClass
{
public class Line_items
{
public string sku { get; set; }
public int quantity { get; set; }
}
public class Address_to
{
public string first_name { get; set; }
public string last_name { get; set; }
public string address1 { get; set; }
public string address2 { get; set; }
public string city { get; set; }
public string zip { get; set; }
}
public class Root
{
public string external_id { get; set; }
public IList<Line_items> line_items { get; set; }
public Address_to address_to { get; set; }
}
}
My c# code:
OrdersClass.Root thisOrder = new OrdersClass.Root();
thisOrder.address_to = new OrdersClass.Address_to();
IList<OrdersClass.Line_items> lineItems = new List<OrdersClass.Line_items>();
I can populate address_to as
thisOrder.address_to.first_name "my first name";
and line_items using:
lineItems.Add(new OrdersClass.Line_items());
lineItems[0].sku = ProductSKU;
lineItems[0].quantity = cartQuantity;
but..I know I'm doing this wrong.
Thanks.
You need to add Line_items:
IList<OrdersClass.Line_items> lineItems = new List<OrdersClass.Line_items>();
var lineItem1 = new OrdersClass.Line_items()
{
quantity = 1,
sku = "sku1"
};
lineItems.Add(lineItem1);
var lineItem2 = new OrdersClass.Line_items()
{
quantity = 2,
sku = "sku2"
};
lineItems.Add(lineItem2);
try to use
lineitems.Add(new OrderClass.Line_items(){
sku = ProductSKU,
quantity = cartQuantity
});
Thanks to those who helped me get my thinking cap back on. Resolved.
line_items.Add did not add the iList to the main "thisOrder" class.
I had instantianted it syntactically correct, but it programmatically correct.
This worked:
thisOrder.line_items = new List<OrdersClass.Line_items>();
Then adding a new ilist:
var lineItem = new OrdersClass.Line_items()
{
quantity = cartQuantity,
sku = printifyProductSKU
};
thisOrder.line_items.Add(lineItem);
Yea. Now on the to the programming challenge:ASYNC Post vs Put.
Thanks.

How To Remove List From Another List In C#

Here I have two list var userListFromFriendTable = mainService.GetUserFromFriend(ChattingUserName); and var getAllUserFromMessageUserTable = mainService.GetalluserfromMessageUser(); whose implementation are
given below.
Now what is want is to remove all the Friend table FriendRequestReceiverName column data of userListFromFriendTable list from MessageUser table MessageUserName column of getAllUserFromMessageUserTable list.
Any help will be grate
public List<Friend> GetUserFromFriend(string chattingUserName)
{
var checkUser = uow.Repository<Friend>().FindBy(x => x.FriendRequestSenderName.ToLower() == chattingUserName.ToLower()).ToList();
return checkUser;
}
public List<MessageUser> GetalluserfromMessageUser()
{
var checkUser = uow.Repository<MessageUser>().GetAll().ToList();
return checkUser;
}
public class Friend
{
public int FriendId { get; set; }
public string FriendRequestSenderName { get; set; }
public string FriendRequestReceiverName { get; set; }
public int IsConfirmed { get; set; }
}
public class MessageUser
{
public int Id { get; set; }
public string MessageUserName { get; set; }
public int IsFriend { get; set; }
}
try this:
var names=userListFromFriendTable.Select(i=> i.FriendRequestReceiverName)
.OfType<string>()
.ToArray();
getAllUserFromMessageUserTable.RemoveAll(r => names.Contains( r.MessageUserName );

How to do Multiple Left Join, Group By, and Concatenate in LINQ

I am trying to display the 'names' of the dialects (from 'lu_dialect_t') of the Parents of a specific Child. I am doing multiple left joins with the LINQ query and now I am hoping to find a way on how to GROUP the query by the 'parent_id' and concatenate the 'name' (of dialects spoken by the parent) to one column and store it in a variable for my ViewModel.
This is my ViewModel:
public class ParentViewModel
{
public int parent_id { get; set; }
public string last_name { get; set; }
public string first_name { get; set; }
public string middle_name { get; set; }
public string ext_name { get; set; }
public Nullable<System.DateTime> birthdate { get; set; }
public string civil_status { get; set; }
public string email_address { get; set; }
public string cell_num { get; set; }
public string tel_num { get; set; }
public string fax_num { get; set; }
public string room_num_or_building { get; set; }
public string street { get; set; }
public string purok { get; set; }
public string subdivision { get; set; }
public Nullable<int> brgy_id { get; set; }
public string city_code { get; set; }
public string province_code { get; set; }
public string mother_tongue { get; set; }
public string educational_attainment { get; set; }
public string occupational_status { get; set; }
public string parent_type { get; set; }
public string deceased { get; set; }
public Nullable<System.DateTime> survey_date_conducted { get; set; }
public string person_who_conducted { get; set; }
public int child_id { get; set; }
public string parent_dialects { get; set; }
}
This is my Controller:
public ActionResult Parents(int id)
{ var query = (from p in db.parent_t
join cp in db.tn_child_parent_t on p.parent_id equals cp.parent_id into tcpGroup
from x in tcpGroup.DefaultIfEmpty()
join c in db.child_t on x.child_id equals c.child_id into cGroup
from y in cGroup.DefaultIfEmpty()
join pd in db.tn_parent_dialect_t on p.parent_id equals pd.parent_id into tpdGroup
from a in tpdGroup.DefaultIfEmpty()
join d in db.lu_dialect_t on a.dialect_id equals d.dialect_id into dGroup
from b in dGroup.DefaultIfEmpty()
where (y.child_id == id)
select new ViewModels.ParentViewModel
{
parent_id = p.parent_id,
last_name = p.last_name,
first_name = p.first_name,
middle_name = p.middle_name,
ext_name = p.ext_name,
birthdate = p.birthdate,
civil_status = p.civil_status,
email_address = p.email_address,
cell_num = p.cell_num,
tel_num = p.tel_num,
fax_num = p.fax_num,
room_num_or_building = p.room_num_or_building,
street = p.street,
purok = p.purok,
subdivision = p.subdivision,
brgy_id = p.brgy_id,
city_code = p.city_code,
province_code = p.province_code,
mother_tongue = p.mother_tongue,
educational_attainment = p.educational_attainment,
occupational_status = p.occupational_status,
parent_type = p.parent_type,
deceased = p.deceased,
survey_date_conducted = p.survey_date_conducted,
person_who_conducted = p.person_who_conducted,
parent_dialects = b.name,
});
return View(query);
}
Right now, the query just displays shows my table like this:
My current progress
But what I want is like this:
The desired result
Please help, I have been trying to find a way to do this for hours. Thank you.
Here is something similar
static void Main(string[] args)
{
var items = Enumerable.Range(0, 10).Select(p => new { Name = "Name" + p%2, LasetName = "LN"+p%2, Dialect = "D"+p });
var data = from item in items
group item by item.Name into g
select new
{
Name = g.Key,
LastName = g.First().LasetName,
Dialect = string.Join(",", g.Select(d=>d.Dialect))
}
;
foreach (var item in data)
{
Console.WriteLine($"Name:{item.Name}, Dialect:{item.Dialect}");
}
Console.WriteLine("Done");
Console.ReadLine();
}
Post process the var query with your group by and youse first for all the single properties you need. If you are using EF you will need to do a ToList first to get the data to memory for the concatenation. Also if there is a lot of data pulling all the rows in memory is not the best.

Read two text files and join columns in a datagridview c#

I have two text files like this:
Text File 1:
Campionato;Data;Home;Away;HSFT;ASFT;HSHT;HSHT
DenDiv1;07.09.2015;Silkeborg;Helsingor;1;0;0;0
DenDiv1;06.09.2015;Naestved;Roskilde;1;1;0;0
DenDiv1;06.09.2015;Lyngby;Vejle;3;2;2;0
Text File 2:
Data;Home;Away;HODD;AODD
07.09.2015;Silkeborg;Helsingor;1.50;4.09;5.71
06.09.2015;Naestved;Roskilde;2.54;3.20;2.63
06.09.2015;Lyngby;Vejle;2.12;3.33;3.20
I need to join and show them in a datagridview. Could you help me please? Thanks! :)
UPDATE: Home and Away columns are both my primary key.
These are the class I'm assuming you already have, or you'll create
public class Data1
{
public string Campionato { get; set; }
public string Data { get; set; }
public string Home { get; set; }
public string Away { get; set; }
public int HSFT { get; set; }
public int ASFT { get; set; }
public int HSHT { get; set; }
public int HSHT2 { get; set; }
}
public class Data2 //you can use inheritance and reduce duplication of properties
{
public string Data { get; set; }
public string Home { get; set; }
public string Away { get; set; }
public double HODD { get; set; }
public double AODD { get; set; }
public double XODD { get; set; } //no name in sample
}
public class CombinedData //you can use inheritance here too
{
public string Campionato { get; set; }
public string Data { get; set; }
public string Home { get; set; }
public string Away { get; set; }
public int HSFT { get; set; }
public int ASFT { get; set; }
public int HSHT { get; set; }
public int HSHT2 { get; set; }
public double HODD { get; set; }
public double AODD { get; set; }
public double XODD { get; set; } //some name
}
You can read the raw data like this
var data1 = File.ReadAllLines(#"C:\YourFolder\Data1.txt").ToList();
data1.RemoveAt(0); //reamoving the header
var data2 = File.ReadAllLines(#"C:\YourFolder\Data2.txt").ToList();
data2.RemoveAt(0); //reamoving the header
Now map them to proper (typed) data list
var dataList1 = new List<Data1>();
foreach(var data in data1)
{
var columns = data.Split(';'); //add data validations
dataList1.Add(new Data1
{
Campionato = columns[0],
Data = columns[1],
Home = columns[2],
//other string properties
HSFT = int.Parse(columns[4])
//other int properties
});
}
var dataList2 = new List<Data2>();
foreach (var data in data2)
{
var columns = data.Split(';'); //add data validations
dataList2.Add(new Data2
{
Data = columns[0],
Home = columns[1],
//other string properties
HODD = double.Parse(columns[3])
//other double properties
});
}
Now you can join them and bind in your Grid.
Note: This is joining on Data column, which will result in 5 rows total.
var combinedDataList = from d1 in dataList1 //Joining on Data here, use the key you have
join d2 in dataList2 on d1.Data equals d2.Data
select new CombinedData { Campionato = d1.Campionato,
Data = d1.Data,
HSFT = d1.HSFT,
HODD = d2.HODD }; //map all properties
yourDataGrid.DataSource = combinedDataList; //check syntax here, not tested
yourDataGrid.Bind();
Update
If you want to join on multiple columns (e.g. Data & Home), use this syntax
var combinedDataList = from d1 in dataList1 //Joining on Data & Home, yields 3 rows
join d2 in dataList2 on new { d1.Data, d1.Home } equals new { d2.Data, d2.Home }
select new CombinedData
{
Campionato = d1.Campionato,
Data = d1.Data,
HSFT = d1.HSFT,
HODD = d2.HODD //map rest of the properties
};
Here is the data class:
public class MyData
{
public String Campionato { get; set; }
public DateTime Data { get; set; }
public String Home { get; set; }
public String Away { get; set; }
public int Hsft { get; set; }
public int Asft { get; set; }
public int Hsht { get; set; }
public int Hsht_2 { get; set; }
public float Hodd { get; set; }
public float Aodd { get; set; }
public float Unknown { get; set; }
}
And here the code to read the files and joining the data:
var file1Data = File.ReadLines(#"File1.csv")
.Skip(1) // Skip header
.Select(line => line.Split(';'))
.Select(elements => new MyData
{
Campionato = elements[0],
Data = DateTime.ParseExact(elements[1], "MM'.'dd'.'yyyy", CultureInfo.InvariantCulture),
Home = elements[2],
Away = elements[3],
Hsft = Int32.Parse(elements[4]),
Asft = Int32.Parse(elements[5]),
Hsht = Int32.Parse(elements[6]),
Hsht_2 = Int32.Parse(elements[7])
});
var file2Data = File.ReadLines(#"File2.csv")
.Skip(1) // Skip header
.Select(line => line.Split(';'))
.Select(elements => new MyData
{
Data = DateTime.ParseExact(elements[0], "MM'.'dd'.'yyyy", CultureInfo.InvariantCulture),
Home = elements[1],
Away = elements[2],
Hodd = float.Parse(elements[3]),
Aodd = float.Parse(elements[4])
});
var joinedData = file1Data.Join(
file2Data,
// Key generation should be optimized. Maybe take a look at http://stackoverflow.com/q/263400/1838048
myData => myData.Data.GetHashCode() + myData.Home.GetHashCode() + myData.Away.GetHashCode(),
myData => myData.Data.GetHashCode() + myData.Home.GetHashCode() + myData.Away.GetHashCode(),
(file1, file2) => new MyData
{
Campionato = file1.Campionato,
Data = file1.Data,
Home = file1.Home,
Away = file1.Away,
Hsft = file1.Hsft,
Asft = file1.Asft,
Hsht = file1.Hsht,
Hsht_2 = file1.Hsht_2,
Hodd = file2.Hodd,
Aodd = file2.Aodd,
Unknown = file2.Unknown
});
myDataGridView.DataSource = joinedData.ToList();
There is a lot of hard-coded stuff and no kind of error checking in there. So a lot of improvement for yourself, but it should give you a good starting point.

EF5 The changes to the database were committed successfully ... Unable to set field/property

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()) {

Categories

Resources