When using entity framework's model designer is it possible to add a property to an entity that is not one of the standard types?
I have these two entities. The one, VirusDescription I would like to add another property which is a class I wrote however when you go to change the type of the property it only gives you basics... i.e. strings, int16...etc. Is there a way to include custom types in the designer?
I can go into the code that the designer generates and just add it myself and everything works fine but I would like the code and the designer to be consistent.
Here is the class definition for the VirusDescription entity which I updated by hand. If there is a way to update the designer from the corresponding code that would work too.
namespace Trojan.Database
{
using System;
using System.Collections.Generic;
public partial class VirusDescriptionItems
{
public string ItemId { get; set; }
public string VirusId { get; set; }
public bool On_Off { get; set; }
public System.DateTime DateCreated { get; set; }
public short AttributeId { get; set; }
public short CategoryId { get; set; }
public virtual Attribute Attribute { get; set; } //Added
public virtual Category Category { get; set; } //Added
}
}
You can create a complex type within the entity model browser and extend the generated class using partial implementations.
Related
My use-case:
I'd like to store a representation of a file tree in my local (SQLite) database using EF.
My model will be a simplified copy a much larger model on a remote SQL database (also in EF)
I'd like to use one, generic entity that self-refers to create a tree structure, and derives its 'type' field from one of the original entity types (FiletypeA, FiletypeB, Folder etc.. using the interface IFileSynchronisable)
I figured the best way was to make the class generic, and deriving a string field from the type using nameof(T) and Type.GetType("FiletypeA"), but I've got stuck trying to instantiate the class when building the model:
public class FileSyncObject<T> where T : class, IFileSynchronisable
{
[Key]
public Guid Id { get; set; }
public long ObjectId { get; set; }
//Can I derive T from some 'ObjectType' field in the record?
public string ObjectType { get { return nameof(T); } }
public long ProjectId { get; set; }
public string AmazonS3Path { get; set; }
public bool IsActive { get; set; }
public string Version { get; set; }
public Guid LocalParentId { get; set; }
public FileSyncObject<T> LocalParent { get; set; }
public virtual ICollection<FileSyncObject<T>> LocalChildren { get; set; }
}
What's the best approach? Is this even possible?
I have two related entities called DataTag and TagSource that look like the following:
public class DataTag : BaseModel
{
[Column("DataTagId")]
public override Guid ID { get; set; }
public string Tag { get; set; }
public Guid TagSourceId { get; set; }
public TagSource TagSource { get; set; }
}
public class TagSource : BaseModel
{
[Column("TagSourceId")]
public override Guid ID { get; set; }
public string Description { get; set; }
public bool IsInternal { get; set; }
public string Source { get; set; }
public ICollection<DataTag> DataTags { get; set; }
}
I am allowing the user to Include the navigation properties through the url like "/api/DataTags?Include=TagSource". The problem is when I include the TagSource, it also includes the collection of DataTags in that object which I don't want unless the user specifies it (For example "/api/DataTags?Include=TagSource.DataTags". Is there any way to stop that property from being loaded when I include the TagSource? I have tried making the properties virtual and turning lazy loading off globally but that didn't work. The reason I haven't marked them virtual is because I am using AutoMapper and I only want to include the navigation properties that the user specifies.
As in the comments you need to create a DTO object. There is a good article here detailing how to do this with WebAPI
http://www.asp.net/web-api/overview/data/using-web-api-with-entity-framework/part-5
Edit.
The problem with this is you will need a lot of different DTO objects for each possible outcome which could become messy. If your return type is JSON you can add this attribute to your properties:
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
Firstly : Apologies for my English.
Secondly : I had the same issue with a code first database model that creates foreign keys this way : public virtual Collection<Object> Objects {get; set;}
and I found a workaround by setting the property setter as private:
public virtual Collection<Object> Objects {get; private set;}
Then the EF cannot populate the Objects collection because with a private set you can only assign a value in constructors.
I am migrating to SQL Server from MySql and re-writing a website in C# (I was/am a vb.net guy) using code-first.
I wrote the following class
namespace DomainClasses.GeographyDb
{
public class PostalCode
{
[Key]
public int PostalCodeId { get; set; }
[Required]
[DataType(DataType.PostalCode)]
public string PostCode { get; set; }
[Required, ForeignKey("City")]
public int CityId { get; set; }
[Required, ForeignKey("TimeZone")]
public int TimeZoneId { get; set; }
[Required, MaxLength(30)]
public string AreaRegionPhonePrefixCode { get; set; }
[MaxLength(10)]
public string TaxRegionCode { get; set; }
public virtual City City { get; set; }
public virtual TimeZone TimeZone { get; set; }
}
I wanted to see what Entity Framework would write if it were creating the class so I created a test project and using code first from database option I imported an existing database of exact same fields as I wrote the custom classes for.
Here is what it produced;
namespace CodeFirstCreationTest
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
public partial class postalcode
{
public long PostalCodeId { get; set; }
[Required]
[StringLength(10)]
public string PostCode { get; set; }
public long CityId { get; set; }
public long TimeZoneId { get; set; }
[Required]
[StringLength(10)]
public string AreaRegionPhonePrefixCode { get; set; }
[StringLength(10)]
public string TaxRegionCode { get; set; }
public virtual city city { get; set; }
public virtual timezone timezone { get; set; }
}
}
I have a number of questions as to the differences;
Why did Entity Framework put all the using statements INSIDE the namespace declaration? I thought they were always to be outside and before the code
StringLength is a data validation annotation. Why did Entity Framework put that attribute on the property, isn't it for UI validation? And now that I think of it I always put Required attribute on classes, is that a data validation annotation as well and not a database annotation?
It created a database class using fluent API and modelbuilder. Is it better to annotate the class properties or do it using the modelBuilder in the OnModelCreating method?
Why did Entity Framework make this class partial and apparently all the classes it generates as partial?
Using statements are sometimes generated inside the actual namespace declaration. Usually there is no difference. Only in some cases is it a bit different. Please see this answer for more info, since it is explained better than I would be able to: https://stackoverflow.com/a/151560/1757695
StringLength and Required are both database annotations and the according operations are executed right before saving the data in the database. For example if you were trying to save a User and the user had a UserName property decorated with Required data annotation, you would get an error only when you called SaveChanges method and not when you assigned the value to the property.
I believe it is personal preference. I prefer data annotations and as little as possible fluent API. There are still some things that you can't do with data annotations but can do with fluent API.
Consider the following model classes:
public class Thing
{
public int Id { get; set; }
[Required]
public Text Subject { get; set; }
[Required]
public Text Body { get; set; }
}
public class Text
{
public int Id { get; set; }
public string Value { get; set; }
}
The model is simple - each Thing must reference to two Text entities. Each Text entry at any point in time should be referenced only by a single entity of any other type (Thing is not the only one).
Is it possible to configure EF5 to automatically delete all referenced Texts when Thing gets deleted (via context.Set<Thing>().Remove), or should it be done with a database trigger?
You just need to configure CASCADE DELETE at database level and don't have to do anything special at Entity framework level.
Given the class:
public class Item
{
[Key]
public int ID { get; set; }
[Display]
public string Name { get; set; }
public string Observation { get; set; }
public DateTime? Done { get; set; }
}
I know i can define my [Key] Attribute and other mapping settings by create a mapping class in another project and inheriting from EntityTypeConfiguration.
but how can i replace the [display] attribute so i don't have to add a reference to System.ComponentModel.DataAnnotations to my common dll?
tell me if i'm not clear enough
You can create your own attribute, then write a class that inherits AssociatedMetadataProvider and reads data from your attribute into a ModelMetadata instance.
Your class would be similar or identical to the built-in version.