Dynamic Linq Order By Parent and Child Collection - c#

I'm using System.Linq.Dynamic.
Given this parent - child (collection) model below, is it possible use OrderBy Client based on createdDate property passing the Id of the specific Address to sort with? Alternatively, Client properties can be used for the main sort as well. It also has to be sorted by Last and First Name.
public class Client
{
public int Id { get; set; }
public string FirstName{ get; set; }
public string LastName { get; set; }
public string Description {get; set;}
public string Type {get; set;}
public virtual ICollection<Address> Addresses { get; set; }
}
public class Address
{
public int Id { get; set; }
public DateTime createdDate { get; set; }
public DateTime modifiedDate { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
}
Is there a generic way to do all the scenarios?
OrderBy(Client.Addresses.Where("Id = #0", idValue).CreatedDate + " ASC , LastName DESC, FirstName DESC")
OrderBy("Type DESC, LastName DESC, FirstName DESC")

When using System.Linq.Dynamic.Core, you should be able to use:
.OrderBy("Type DESC, LastName DESC, FirstName DESC")
See also : https://dynamic-linq.net/basic-simple-query#ordering-results

Related

Entity Framework Code First Renaming Columns/Keys

I have an Employee table that links employees to their contact info. I have it set up like so:
[ForeignKey("AddressId")]
public virtual Address Address { get; set; }
[ForeignKey("HomePhoneId")]
public virtual PhoneNumber HomePhone { get; set; }
[ForeignKey("WorkPhoneId")]
public virtual PhoneNumber WorkPhone { get; set; }
[ForeignKey("CellPhoneId")]
public virtual PhoneNumber CellPhone { get; set; }
When I try to load employees from the database, however, it automatically renames the columns, completely overriding the attributes:
Invalid column name 'PhoneNumber_Id'.
Invalid column name 'PhoneNumber_Id1'.
Invalid column name 'PhoneNumber_Id2'.
Invalid column name 'Address_Id'.
Why is it doing this?
As stated by #mcbowes, it is hard to tell without seeing the rest of your Employee class, but most likely you are missing the following in your class:
public int AddressId { get; set; }
public int HomePhoneId { get; set; }
public int WorkPhoneId { get; set; }
public int CellPhoneId { get; set; }
The IDs were all properly specified for each navigation property. It seems the problem had to do with the navigation properties on each PhoneNumber and Address object that linked back to the Employee. I don't need them for now, so removing those navigation properties corrected the issue.
As an expansion on #peinearydevelopment set up your PhoneNumber:
public class PhoneNumber
{
public PhoneNumber(string name, int areaCode, string number)
{
Name = name;
AreaCode = areaCode;
Number = number;
}
public int ID { get; set; }
public string Name { get; set; }
public int AreaCode { get; set; }
public string Number { get; set; }
}
}
Set up your Employee:
public class Person
{
public Person(string first, string last, PhoneNumber home, PhoneNumber cell)
{
First = first;
Last = last;
HomeNumber = home;
CellNumber = cell;
}
public int ID { get; set; }
public string First { get; set; }
public string Last { get; set; }
public int HomePhone_ID { get; set; }
public int CellNumber_ID { get; set; }
public virtual PhoneNumber HomeNumber { get; set; }
public virtual PhoneNumber CellNumber { get; set; }
}
}
And your Context
public class PersonContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<PhoneNumber> PhoneNumbers { get; set; }
}
As you can see, relationships are maintained, but you do need to explicitly tell your application which fields hold the identifiers, not just which tables have the relationships.

Sharing of Property in a DTO using Category attribute c#

I'm working on Employee Model, it contains all the information about the Employee already I posted the same in How to use the DTO efficiently based on Scenario in C#. How could I share the single property for the multiple groups using Category attribute c#.
For Example:
public class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string HomePhone { get; set; }
public string MobilePhone { get; set; }
}
I'm having the following four methods for fetching records of Employee
public Employee GetEmployeeName(int id)
{
// The return should contain only FirstName, MiddleName and LastName.
// The rest of the properties should be non-accessable (i.e., Private)
}
public Employee GetEmployeeContacts(int id)
{
// The return should contain only EmailAddress, HomePhone and MobilePhone.
// The rest of the properties should be non-accessable (i.e., Private)
}
public Employee GetEmployeeNameEmail(int id)
{
// The return should contain only FirstName, MiddleName, LastName and EmailAddress.
// The rest of the properties should be non-accessable (i.e., Private)
}
public Employee GetEmployee(int id)
{
// It should return the entire Employee object
}
How could I achieve this? could you please any one help in this regards.
A sample, this is the common use for DTO:
public class EmployeeNameDto
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
public EmployeeNameDto GetEmployeeName(int id)
{
Employee emplpoyee = employeeRepository.Find(id):
return new EmployeeNameDto() {
EmployeeId = emplpoyee.EmployeeId,
FirstName = emplpoyee.FirstName,
MiddleName = emplpoyee.MiddleName,
LastName = emplpoyee.LastName
};
}
Or
public class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get;
set {
if (condition == false)
throw new Exception(" is Read Only !")
}
}
public string MiddleName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string HomePhone { get; set; }
public string MobilePhone { get; set; }
}

Entity Framework mapping one class across two tables with a condition

I'm trying to map one class to two database tables. I have a Person Class that maps to a Person table and an Address table. My problem is I only want to select the Primary Address Line (IsPrimary = 1) of the Address table and I can't find or figure out how to do this.
I'm using Entity Framework v6 CodeFirst and I trying to create the EntityTypeConfiguration<T> class
The domain class is...
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
// Primary Address
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string AddressPostCode { get; set; }
}
and the database tables look like this...
Table: Person
Int PersonId (PK)
Varchar(20) FirstName Not Null
Varchar(20) LastName Not Null
Table: Address
Int AddressId (PK)
Int PersonId (FK)
Varchar(25) AddressLine1 Null
Varchar(25) AddressLine2 Null
Varchar(25) AddressLine3 Null
Varchar(10) PostCode Not Null
Bit IsPrimary Not Null
Basically one Person can have multiple addresses but only One Primary Address.
If you are using Entity Framework, probably you have these following classes with a one to many relation:
public class PersonEntity
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<AddressEntity> Addresses { get; set; }
}
public class AddressEntity
{
public int AddressId { get; set; }
public int PersonId { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string AddressPostCode { get; set; }
public bool IsPrimary{ get; set; }
}
And as you mentioned in you'r question, this is the person viewmodel:
public class PersonViewModel
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
// Primary Address
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string AddressPostCode { get; set; }
}
Finally you can use the following linq code:
var result = ctx.PersonEntity
.Where(c => c.Addresses.FirstOrDefault(X = > X.IsPrimary == true)).ToList();
var personViewModels = result
.Select(c => new PersonViewModel{
PersonId = c.PersonId ,
FirstName = c.FirstName ,
LastName = c.LastName,
AddressLine1 = c.Addresses != null ? c.Addresses.FirstOrDefault().AddressLine1 : String.Empty ,
AddressLine2 = c.Addresses != null ? c.Addresses.FirstOrDefault().AddressLine2 : String.Empty ,
AddressLine3 = c.Addresses != null ? c.Addresses.FirstOrDefault().AddressLine3 : String.Empty });

EntityFramework changing my query - EntityCommandExecutionException

I'm getting a 'EntityCommandExecutionException' and
An error occurred while executing the command definition. See the inner exception for details.
with an inner message of
Invalid column name 'Department_ID'
This seems to be the query executed from this line of code:
List<Employee> _employees = employeeContext.Employees.ToList();
SELECT [Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[Name] AS [Name],
[Extent1].[Gender] AS [Gender],
[Extent1].[City] AS [City],
[Extent1].[DepartmentID] AS [DepartmentID],
[Extent1].[DateOfBirth] AS [DateOfBirth],
[Extent1].[Department_ID] AS [Department_ID]
FROM [dbo].[tblEmployee] AS [Extent1]
This is wrong considering there is no Department_ID, I have no idea where it is getting this from. This is the Employee class model:
[Table("tblEmployee")]
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public int DepartmentID { get; set; }
public DateTime DateOfBirth { get; set; }
}
[Table("tblDepartment")]
public class Department
{
public Int16 ID { get; set; }
public string Name { get; set; }
public List<Employee> Employees { get; set; }
}
Not sure what to do. Any ideas?
The Department_ID is coming by virtue of the relationship in your Department class. You have a List Employees there which automatically assumes a column called Department_ID in your Employee table.
What you need to do is add a virtual property called Department in your Employee table instead of adding the DepartmentID
[Table("tblEmployee")]
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public virtual Department Department { get; set; }
public DateTime DateOfBirth { get; set; }
}
If you need to maintain the column name as DepartmentID or you need access to the property DepartmentID in code, then you need to use the ForeignKey attribute as shown below:
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public int DepartmentID { get; set; }
[ForeignKey("DepartmentID")]
public virtual Department Department { get; set; }
public DateTime DateOfBirth { get; set; }
}
I would also recommend that you maintain the List as virtual.

Refactor EF6 entity to instead of use multiple properties use a complex type

I have a class customer that contains address properties, phone properties and fax properties, but I want to take off the address, phone properties to complex types. Does properties are already in the database as columns.
[Table("tblCustomer")]
public partial class Customer : Entity
{
[Key]
public int CustomerID { get; set; }
[StringLength(10)]
public string CustomerCode { get; set; }
[StringLength(60)]
public string AddressLine1 { get; set; }
[StringLength(70)]
public string AddressLine2 { get; set; }
[StringLength(35)]
public string City { get; set; }
[StringLength(2)]
public string State { get; set; }
[StringLength(10)]
public string ZipCode { get; set; }
[StringLength(15)]
public string PhoneNo { get; set; }
[StringLength(3)]
public string PCountryCode { get; set; }
[StringLength(3)]
public string PAreaCode { get; set; }
[StringLength(7)]
public string PPhoneNo { get; set; }
[StringLength(3)]
public string FCountryCode { get; set; }
[StringLength(3)]
public string FAreaCode { get; set; }
[StringLength(7)]
public string FaxNumber { get; set; }
[StringLength(3)]
public string CountryCode { get; set; }
}
how to refactor this into:
[Table("tblCustomer")]
public partial class Customer : Entity
{
[Key]
public int CustomerID { get; set; }
[StringLength(10)]
public string CustomerCode { get; set; }
public Address Address { get; set; }
public Phone Phone { get; set; }
public Phone Fax { get; set; }
}
without conflicting with what already exist in the database?
Your address class should be annotated with the ComplexType attribute and you'd need to explicitly map the column names:
[ComplexType]
public class Address
{
[Column("street")]
public string Street {get; set;}
// Other properties
}

Categories

Resources