How to map a Point in the entity framework? - asp.net

I am developing an API in the .net core and using the Framework entity.
My bank already existed and in one of the tables I have a Point type field to store coordinates (Spatials).
I'm not using any automatic approach (Ex: code First, DataBase First ...), I am modeling my classes myself.
To map this Point field I did it as in primitive types, I believe to be wrong, and I'm getting an error:
System.InvalidOperationException: 'The property 'Address.LatLong'
could not be mapped, because it is of type 'Point' which is not a
supported primitive type or a valid entity type. Either explicitly map
this property, or ignore it using the '[NotMapped]' attribute or by
using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.'
public class Address:BaseModel
{
[Required]
[StringLength(30)]
public string Street { get; set; }
[Required]
public int Number { get; set; }
[StringLength(45)]
public string Observation { get; set; }
[Required]
[StringLength(20)]
public string PostalCode { get; set; }
[ForeignKey(nameof(City))]
[Required]
public int CityId { get; set; }
public virtual City City { get; set; }
public Point LatLong { get; set; } //this is the field
}

if you wanna use that point for other address , so u should add something like this to your point Class :
public virtual ICollection<Address> Address{ get; set; }
and if you dont wanna use that point for another adress , u can bring Lat and Long to your adress class.
by the way i think add this public virtual ICollection<Address> Address{ get; set; } should fix your problem

Related

Using the same generic foreign key field (KeyId) along with a (Type) field for a single table in EntityFramework

I have a class called Address with the following properties:
public int Id { get; set; }
public string Name { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string ZipCode { get; set; }
public int KeyId { get; set; }
public AddressType Type { get; set; }
The plan is for AddressType to be an enum of either: Customer, Vendor, or Location and the KeyId to be the Foreign Key from either the Customer, Vendor, or Location.
Is this something that can be done correctly with Entity Framework or should I be making 3 separate classes CustomerAddress, VendorAddress, LocationAddress.
You need to generate an entity inheritance structure from a single database table. Can achieve that by using a Table per Type approach
TBT Entity Framework
Group the common properties into a "Base" entity, and then use a discriminator (in your case the AddressType) for specializing the object.
I looks like you have three tables Customer, Vendor, or Location and you want to save Address for each.
Then instead of adding AddressType in Address table, you should include AddressID in each table as Foreign key and must have a Address navigation property in each table.

Is ok to add [BsonAttribute] to POCOs?

I have an application, structured like this:
Application.Domain
Application.Web.Mvc
Application.MongoDb
In Application.Domain i keep all the POCOs of the application (the domain models).
public class Product
{
public string Id { get; set; }
public string ProductName { get; set; }
public DateTime CreatedDate { get; set; }
}
Now, because i am using MongoDb, i also need to use some of the [BsonAttribute], in order to customize the serialization process.
For example:
public class Product
{
[BsonId]
public string Id { get; set; }
public string ProductName { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Local, DateOnly = true)]
public DateTime CreatedDate { get; set; }
}
If i add these attributes, i will need to also add a reference to MongoDB.Bson.Serialization.Attributes in the Application.Domain project, which i want to avoid.
I think the correct way to do this is to create mapping objects in the Application.MongoDb project, and always map them from POCO to MongoObjects and the other way around every time i work with MongoDb repos.
If this is the correct solution, isn't this a bit overkill?

Tree structure with reference to root in Entity Framework

I'm trying to model a tree structure for orders in Entity Framework. Right now I've go the following:
public class ProjectModel
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int CustomerId { get; set; }
public virtual List<ProjectNode> Nodes { get; set; }
}
public class ProjectNode
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Path { get; set; }
public int? ParentId { get; set; }
[ForeignKey("ParentId")]
public virtual List<ProjectNode> Children { get; set; }
}
What I need to be able to do is get a reference to the root ProjectModel at any level of ProjectNode in order to authorize a given user actually having permission to view and change the project which contains the ProjectNode.
public class ProjectNode {
public int ProjectId { get; set; } //<-- this
...
public class ProjectModel {
[Key]
public int Id { get; set; } //<-- containing the value of this
}
My question is whether its possible to have a theoretical ProjectId property populated at every level of the tree structure, or if I need to set it manually.
I had something working that at first blush appeared to allow this functionality, but upon further investigation only populated the ProjectId for ProjectNodes contained in the ProjectModel's Nodes property.
It seems to me like it would be super inefficient to recurse backwards through the structure to get to the root.
Credit due to #TestWell for this answer -
Apparently, all I needed to do for EF to automatically populate the ProjectId property on the ProjectNode was to change the name of the Id property in ProjectModel to ProjectId.
Unfortunately, this doesn't appear to work if I add a CustomerId property to the ProjectNode that I would like automatically populated from the property of the same name on the node's root ProjectModel, which I realized is the more efficient solution to what I'm trying to do.

Automapper with Column Order Data Annotation

I am having an issue on application start up when I setup my AutoMapper config. It is throwing an exception when creating the mapping for a business object to a data object. The issue appears to be coming from the use of data annotations. It is worth mentioning that the mapping from data object to business object works just fine.
The exception that I get is a CustomAttributeException:
'Order' property specified was not found.
AutoMapper.config Mapping:
Mapper.CreateMap<Note, NoteData>();
The database object is defined as:
public class NoteData
{
[Key]
[Column(Order = -1)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual Guid Id { get; set; }
[Timestamp]
[ConcurrencyCheck]
[Column(Order = 999)]
public virtual byte[] Version { get; set; }
[Required]
public virtual DateTime Date { get; set; }
[Required]
[StringLength(500)]
public virtual string Value { get; set; }
public virtual bool IsDeleted { get; set; }
[Required]
public virtual UserData CreatedBy { get; set; }
}
I have tried ignoring the fields that have Column Order data annotations on them but that did not resolve the issue.
When I comment out the Order data annotations, Automapper has no issues. So my main question is there a way to configure AutoMapper to work with the Column Order data annotations?
Order can't be negative one. And since an answer needs at least 30 characters let me add MSDN's doc:
Gets or sets the zero-based order of the column the property is mapped to.

Is it OK to declare a DBSet in the context for both a base table and a derived table?

I have a SalesOrder table which inherits from a SalesDocument table using Table Per Type Inheritance
The ( simplified) table classes are;
[Table("SalesDocumentHeaders")]
public abstract class SalesDocumentHeader
{
[ForeignKey("CreatedByUserId")]
public virtual User CreatedBy { get; set; }
[Required]
public int CreatedByUserId { get; set; }
[Required]
public virtual DateTime? DocumentDate { get; set; }
[Required]
public String ReferenceNumber { get; set; }
}
[Table("SalesOrders")]
public class SalesOrder : SalesDocumentHeader
{
[Required]
public String CustomerOrderNumber { get; set; }
public DateTime? DeliverBy { get; set; }
public virtual SortableBindingList<SalesOrderLine> Lines { get; set; }
}
The context contains
public DbSet<SalesOrder> SalesOrders { get; set; }
public DbSet<SalesDocumentHeader> SalesDocumentHeaders { get; set; }
It doesn't strictly need the SalesOrders DBSet, since SalesOrder inherits from SalesDocumentHeader however I find it convenient.
It seems to work OK, but I am worried that there are 2 ways of reaching the same record , am I doing something wrong?
Usually you only need to keep the DBSet for the base table. This helps when you have multiple derived tables (call them A and B) and you need to decide the actual type dynamically.
For example if you have another entity which references type A or B (like a user can have different types of contact information), you can reference the base table and EF will resolve the correct concrete type at runtime. Though of course this adds some extra casting code.

Resources