Its good to use [NotMapped] in side EF code first Model - entity-framework

In My Case, I have a question about in my model I need one extra field like this
public class PassportStamp
{
[Key]
public int Id { get; set; }
[MaxLength(10, ErrorMessage = "BloggerName must be 10 characters or less"), MinLength(5)]
public string BloggerName { get; set; }
[Required]
public string Title { get; set; }
[NotMapped]
public string BlogCode
{
get
{
return Title.Substring(0, 1) + ":" + BloggerName.Substring(0, 1);
}
}
}
Can I use this way or can I create a separate view model for this field
and also can I use data Data Annotations at this way or create a separate view model for that

You are right, you can use [NotMapped] in your case. [NotMapped] is useful in those scenarios where you don't want to create a table column, but you want to use it with some custom properties.
e.g. In your model class Student, there are fields FirstName and LastName. If you client needs FullName of Student object. Then you can simply use [NotMapped] in this case. Because there is no use to create a separate column for this in the table. And you don't need to write a custom logic while using FullName throughout the application.

Related

Specify a Parent-Child relationship in EF Core without using identity columns

Specify a Parent-Child relationship in EF Core without using identity columns
What's an efficient way within Entity Framework Core 5 (C#) to work with the data in a hierarchial table that is linked via non-identity columns.
Here's my primary class:
public class ServiceProvider
{
[Key]
public int Id { get; set; }
public string ParentSPCode { get; set; }
public string SPCode { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ContactEmail { get; set; }
public string Status { get; set; }
}
The SPCode value is unique, which I enforce via C# code. The ParentSPCode may be null or must match an existing SPCode. Again I enforce this via C# code.
I want this table to hold any number of levels of parent-child (1 or more) records, as defined by ParentSPCode-SPCode pairs.
I can retrieve these records via a complex hierarchy of LINQ "joins", but I am thinking there must be a cleaner way by defining the appropriate EF Core 5 relationship.
If I was in SQL Server, I would do this via a CTE.
I want to be able to bring in the child records in a manner similar to .Include(q => q.ParentSPCode == x.SPCode).

EF Core - Populate an UnMapped column from raw SQL?

I have a query where I'm doing a Count on a specific join/column - If I run this code with the "Clicks" [NotMapped] attribute removed, all the values populate properly - but then inserts fail since "Clicks" is not a valid column name. When I mark the column as [NotMapped] then it's not populating from this statement. How can I use raw SQL and populate a [NotMapped] column?
Code:
var query = db.URLs.FromSqlRaw(
#"SELECT [u].[Key], [u].[Url], COUNT(c.Id) AS [Clicks]
FROM[URLs] AS[u]
LEFT JOIN[Clicks] AS[c] ON[u].[Key] = [c].[ShortUrlKey]
GROUP BY[u].[Key], [u].[Url]")
.AsQueryable<ShortURL>();
var urls = query.ToList();
Model (works for inserts, but doesn't populate Clicks property):
public class ShortURL
{
public string Key { get; set; }
public string Url { get; set; }
[NotMapped()]
public int Clicks { get; set; } // doesn't populate from raw query
}
Model (works for queries, but fails on inserts)
public class ShortURL
{
public string Key { get; set; }
public string Url { get; set; }
public int Clicks { get; set; } // not in DB
}
This is not the best method but is an option you can use to solve your problem:
Create a new DbSet in you DBContext list:
public DbSet<YourMode> actual_table_name { get; set; }
public DbSet<CopyWithUnmappedModel> arbitary_table_name { get; set; }
Duplicate the entire YourModel under the YourModel and give it any name you want (CopyWithUnmappedModel)
Remove all the NotMapped fields and place them in the arbitary model with the NotMapped attribute
Use the arbitary_table_name instead of actual_table_name where you want to only Read the date. Since you are not writing to the table the name of the table does not mater. And use the the first one actual_table_name for writing.

Entity Framework Model with a max child record property

I have a couple of simple EF models with a parent child relationship. The children are essentially audit records. I am wanting to use the audits to get the min date to determine the "Create Date" of the parent.
The two models directly match the SQL Database as you would expect with the exception of the derived "CreatedDate" field that I was hoping for EF to translate into a simple "Max" subquery.
I am using the EF Repository Pattern with the Unit Of Work pattern and trying to keep things really simple with the SQL Server doing the MAX query.
I have tried using automapper to map in my service layer but this generates an SQL query per parent.
Any ideas?
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public virtual IEnumerable<Audit> Audits { get; set; }
//Read only create date and problem property
[NotMapped]
public DateTime CreatedDate
{
get
{
return Audits.Max(a => a.AuditDate);
}
}
}
public class Audit
{
public int Id { get; set; }
public int ItemId { get; set; }
public DateTime AuditDate { get; set; }
}
I could well be wrong but I don't think EF will support this; either you pull in all of the Audit records for an Item
e.g.
var item = _context.Items.Include("Audit").FirstOrDefault(i=>i.Id==1)
in which case the method will work.
Or, you could create a view mapped to a new entity (or QueryType if you are using EF Core) that contains Id, Name, and CreateDate only.
e.g
SELECT Id,Name=CreateDate=Max(CreateDate) from Items group by Id,Name
Now since I always use views for this kind of thing I do stand to be corrected on the first point!

How do I include an unmapped field in a POCO class

I'm new to the EF and am just experimenting. Can someone tell me if the following is possible. Given a (product) table in the DB like so:
Id Cost DescriptionFK
-- ---- -------------
? ? ?
I want the corresponding POCO class (entity) to appear like:
public class Product
{
public int Id { get; set; }
public decimal Cost { get; set; }
public string Description { get; }
}
Note that the "Description" in the class is a read-only string (no setter), but it's a key in the table. I'm calling a stored procedure to pull this off (converting the key to its corresponding string and returning the above class), but if I now do something like:
// ...
product.Cost = 20;
myContext.SaveChanges();
I get an exception complaining that there's no mapping for the "Description" string. I removed the mapping because it's read-only and I don't need to include the "DescriptionFK" in the class itself. Is there some way to pull this off (POCO only). Thanks very much.
If you are just looking to have the Description property as a calculated field, add [NotMapped] to your the property to explicitly exclude it and then generate the database:
public class Product
{
public int Id { get; set; }
public decimal Cost { get; set; }
[NotMapped]
public string Description { get; }
}
AFAIU, it is not possible.
"You always need at least one navigation property to create a foreign key constraint in the database."
EF Code First foreign key without navigation property

EF Code First Multiple entities to same table

I am interested in how I can map two entities to same table, by using code first. Here's an example:
public class User
{
[Key]
public int UserId { get; set; }
public string Name { get; set; }
public byte Age { get; set; }
public bool Active { get; set; }
public DateTime Created { get; set; }
}
public class UserViewModel
{
[Key]
public int UserId { get; set; }
public string Name { get; set; }
public byte Age { get; set; }
}
Basically I'm fed up with building repositories. I want to map all possible models for configuration portal, user portal, other services in modelbuilder and just use DbContext for everything. I want to set User class as top of the hierarchy and a class that builds the database, while all other models should just be there for various applications.
I don't want to use automapper. I've also done fair amount of manual coding which just wasted my time, and every single modification requires me to go back to repository and recode - which annoys me.
I've tried to use this in modelbuilder, but it warns me that hierarchy is not valid:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().Map(p => { p.ToTable("Users"); });
modelBuilder.Entity<UserViewModel>().Map(p => { p.ToTable("Users"); });
}
Also keep in mind that I'm not trying to achieve "Table splitting". I don't want my table to be split in two entities, I want rather to have all columns nullable, except one with primary key, and allow different applications/web services/web portals to populate as much data as they've been granted access for.
Thanks for all the tips :)
You can't. One table = one entity (except advanced mappings like mentioned table splitting and TPH inheritance). View model is not and entity. It is just view on data / projection so handle it that way. You will always work with User and project user to view model you need:
var view = from u in context.Users
select new UserViewModel
{
UserId = u.UserId,
Name = u.Name,
Age = u.Age
};
Make this as reusable method returning IQueryable<UserViewModel> and you can do whatever you want.
Table Per Hierarchy TPH inheritance in entity framework with code first
https://www.youtube.com/watch?v=2i7jahkpeQ8&list=PL6n9fhu94yhUPBSX-E2aJCnCR3-_6zBZx&index=19