Is there a method to choose only some specific fields of a table using Automapper or EntityFramework? - asp.net-mvc-4

I have a table in SqlServerDatabase. Table name is User(Id,Name,Paswd) and Im using automapper in Mvc4. Now i want only specific fields or 2 fields from the table instead of whole table, using automapper.how to do??

basically if the 2 objects have the same fields as in the little example
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Paswd { get; set; }
}
public class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Paswd { get; set; }
}
You just have to ignore the field
Mapper.CreateMap<User, UserDto>()
.ForMember(o => o.Paswd, m => m.Ignore());
You can find a lot of usefull example and features here
Automapepr Wiki

Related

Doubts about EF Core 2.1 Relations

I am working on Entity Framework Core Code First approach and ASP.Net Core 2.1 making 3 tables:
Person class
public class Person
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public PeopleProfessions PeopleProfessions { get; set; }
}
Professions' class
public class Profession
{
public string Id { get; set; }
public string Name{ get; set; }
public PeopleProfessions PeopleProfessions { get; set; }
}
peopleprofessions' class
public class peopleprofessions
{
[ForeignKey("PersonId ")]
public string PersonId { get; set; }
public ICollection<Person> People { get; set; }
[ForeignKey("ProfessionId")]
public string ProfessionId{ get; set; }
public ICollection<Profession> Professions { get; set; }
}
On my Context:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<peopleprofessions>().HasKey(up => new { up.PersonId, up.ProfessionId });
}
Bearing this in mind:
People can have multiple professions.
The professions table is only for reading stored data like "Accountant".
I have doubts about how I can make table 3 only contain the foreigners and that it can meet the needs that I just mentioned.
I have tried to make the relationship appropriately but I also noticed that in tables 1 and 2 it requests both Id of the table people's professions.
I don't know if I am lost or if I am looking wrong or if there is an alternative to that situation. Thanks for any help you can give me.
You have the use of Collections on the navigation items a bit backwards. For your primary entities (Person and Profession), they should have collections, since it's one-to-many. But for the PeopleProfessions, each record is a single link to a specific entity, so no collection there just a direct object reference.
public class Person
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<PeopleProfessions> PeopleProfessions { get; set; }
}
public class Profession
{
public string Id { get; set; }
public string Name{ get; set; }
public ICollection<PeopleProfessions> PeopleProfessions { get; set; }
}
public class PeopleProfessions
{
public string PersonId { get; set; }
public Person Person { get; set; }
public string ProfessionId { get; set; }
public Profession Profession { get; set; }
}
You can, but don't need to specify a ForeignKey attribute because you are following EFs naming conventions(it will figure it out for you). Your OnModelCreating looks correct for the composite key.
You may want to consider removing the plural from PeopleProfessions (just call the class PeopleProfession) since one instance represents a single People-Profession relationship. I typically do this and but the navigation name in the entities remains plural, since it can represent more than one, i.e.
public ICollection<PeopleProfession> PeopleProfessions { get; set; }

Handling queries over related documents in RavenDB

I have a project where I have a set of forms:
public class Form
{
public string Id { get; set; }
public string Name { get; set; }
public IList<string> FieldValueIds { get; set; }
public string UserId { get; set; } // the user who completed the form.
public string FormTemplateId { get; set; }
}
Which each "implement" a form template selected at creation of the form.
public class FormTemplate
{
public string Id { get; set; }
public string Name { get; set; }
public IList<string> FieldIds { get; set; }
}
Which defines which fields are present within the form. Each field
public class FormField
{
public string Id { get; set; }
public string Name { get; set; }
public string Caption { get; set; }
public ValueType DataType { get; set; } // Enum specifying the type of data this field accepts.
}
Stores information about the field such as a description and what type it is expecting. Each FormField can be present in multiple FormTemplates with the values for the form being stored as FieldValue objects related to the Form itself.
public class FieldValue
{
public string Id { get; set; }
public string FieldId { get; set; }
public string ValueAsJsonString { get; set; }
}
Other objects include the User Object:
public class User
{
public string Id { get; set; }
public string Username { get; set; }
public string GivenNames { get; set; }
public string Surname { get; set; }
}
I would like to be able to perform a query to find all Forms completed by a user with a specified name, or all Forms where a field with name X has value Y and so forth.
I have looked into usage of indexes as specified in the documentation Indexing related documents, however the implementation as presented in the documentation threw a NotSupportedException when I implemented the example as follows:
class FormTemplates_ByFieldAndName : AbstractIndexCreationTask<FormTemplate>
{
public class Result
{
public string Name { get; set; }
public IList<string> FieldNames { get; set; }
}
public FormTemplates_ByFieldAndName()
{
Map = FormTemplates => from FormTemplate in FormTemplates
select new
{
Name = FormTemplate.Name,
FieldNames = FormTemplate.FieldIds.Select(x => LoadDocument<FormField>(x).Name)
};
}
}
// in code:
IList<FormTemplate> TestResults = session.Query<FormTemplates_ByFieldAndName.Result, FormTemplates_ByFieldAndName>()
.Where(x => x.Name == "TemplateName" || x.FieldNames.Contains("FieldName"))
.OfType<FormTemplate>()
.ToList();
As best as I can tell this was implemented correctly, however I have seen a suggestion to replace the .Contains with a .Any implementation instead. In lieu of this I have been experimenting with a different approach by applying successive .Where arguments. Like so:
var pre = session.Query<FormTemplates_ByFieldAndName.Result, FormTemplates_ByFieldAndName>();
var pr2 = pre.Where(x => x.Name == "TypeTest25");
List<FormTemplate> TestResults = pr2
.Where(x => x.FieldNames.Any(a => a == "field25"))
.OfType<FormTemplate>()
.OrderByScoreDescending()
.ToList();
Modifying the system to perform in a more factory oriented approach by applying successive filters based on a supplied string in a pre-specified format.
Is this the way I should be going for this implementation and if not what should I be changing? In particular if I am to proceed with the Indexing option how would I apply this technique to the nested relationship between Forms and FormFields through FormTemplates.
You seems to be trying to do this in a way that is mostly relational, but you don't have to.
Instead of trying to have a set of independent documents that each has part of the data, just store it all in a single document.
public class Form
{
public string Id { get; set; }
public string Name { get; set; }
public IList<FieldValue> FieldValues { get; set; }
public string UserId { get; set; } // the user who completed the form.
public string FormTemplateId { get; set; }
}
public class FieldValue
{
public string Id { get; set; }
// can store the value directly!
//public string ValueAsJsonString { get; set; }
public object Value {get; set; }
}
This will generate documents that looks like this:
{
"Id": "forms/1234",
"Name": "Tom",
"FieldValues": [
{
"Id": "FromValues/SchoolDistrictName",
"Value": "ABi195"
}
],
"UserId": "users/tom",
"FormTemplateId": "FromTemplate/1234"
}
Which is a much more natural way to model things.
At that point, you can use RavenDB's ability to index dynamic data, see the docs here:
https://ravendb.net/docs/article-page/3.5/Csharp/indexes/using-dynamic-fields

Generate meta data from EntityFramework with partial class

I have a class like
using System;
using System.Collections.Generic;
public partial class Order
{
public Order()
{
this.OrderDetails = new HashSet<OrderDetail>();
}
public int OrderID { get; set; }
public string OrderNo { get; set; }
public System.DateTime OrderDate { get; set; }
public int BuyerID { get; set; }
public int UserID { get; set; }
public virtual Buyer Buyer { get; set; }
public virtual User User { get; set; }
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
}
which is provide by EntityFramework.
I have got meta data of the entityframework properly. But I want to add new two Columns as follows
public partial class Order
{
public string BuyerName { get; set; }
public string UserName { get; set; }
}
"After adding new columns when I fetch metadata but system does not return "BuyerName" and UserName" in metadata. what should Do?
I think "BuyerName" and UserName" are two new columns added to "Order" table.
In this case you need to update the Database Model (*.edmx file) (Update Model From DataBase) to get the mapping information for these new columns.
If you want to add only these properties to the Order class without any real columns in the database, then no need of update the Edmx file.

MVC4 how to load related data without Navigation Properties

I an fairly new to MVC, and have created an MVC4 application using EF-database-first. The database does not contain foreign key definitions and I can't add them (I don't own the database). Here are two example classes from the database:
public partial class Allocation
{
public int AllocID { get; set; }
public int DeptID { get; set; }
public decimal AllocationPercent { get; set; }
}
public partial class Department
{
public int DeptID { get; set; }
public string DeptName { get; set; }
public string Account { get; set; }
}
The default Allocation Index page shows the department ID. I want to show the department name instead. How can I do this without navigation properties?
I tried
public class AllocationController : Controller
{
private Entities db = new Entities();
//
// GET: /Allocation/
public ActionResult Index()
{
return View(db.Allocation.Include(d => d.DeptID).ToList());
}
...
but this gives an error ("A specified Include path is not valid. The EntityType 'TESTModel.Allocation' does not declare a navigation property with the name 'DeptID'.")...
I'm not sure how to code eager-loading or explicit-loading without navigation properties either, which prompted this question. Efficiency-wise, I don't believe it matters which way I load the related information, so any help in any direction would be appreciated.
The database does not have to have definitions, as long as the fields are there and the entities have been placed in the database with referential integrity in mind. All you need to do is let entity framework know about the relationship. This is done with the virtual keyword to create "Navigational Properties".
public partial class Allocation
{
public int AllocID { get; set; }
public int DeptID { get; set; }
public decimal AllocationPercent { get; set; }
public virtual Department Department { get; set; } /* this is your nav property */
}
public partial class Department
{
public int DeptID { get; set; }
public string DeptName { get; set; }
public string Account { get; set; }
}
Now you can do:
db.Allocation.Include(a => a.Department).ToList()
There may be an error which requires you to use a foreign key definition (although I do not think so). If this is the case, you will need to decorate your navigation property like this
[ForeignKey("DeptID")]
public virtual Department Department { get; set; }
You may also try it this way:
public int AllocID { get; set; }
[ForeignKey("Department")]
public int DeptID { get; set; }
public decimal AllocationPercent { get; set; }
public virtual Department Department { get; set; }
With navigation properties, Travis J's answer is what you need.
If you don't want to use navigation properties, assuming your DB context has a set called Departments, you could do smth like this:
var deptId = db.Allocation.DeptID;
var departments = db.Departments.Where(p => p.DeptID == deptId);
return View(departments.ToList());

PetaPoco to return self-referencing hierarchy

How would one write a query/method to return a POCO that is from a self-referencing database as shown in this question
Firstly you would map it a flat class. eg. db.Fetch<CategoryDb>("select * from categories");
public class CategoryDb {
public int Id { get; set; }
public string Name { get; set; }
public int ParentCategoryId { get; set; }
}
From here I would then create a new Object that self referenced itself. (You could use the existing object with the ParentCategory having the [Result] attribute on it.)
public class Category {
public int Id { get; set; }
public string Name { get; set; }
public Category ParentCategory { get; set; }
}
You could then take this and convert your flat list into a nested list.
I do have code somewhere that can do this, and for which it also provides searching methods etc, but its not on this computer. I will update tomorrow with a link to the code.