Using Microsoft.Azure.Mobile.Server EntityData, I have a class that looks like
public abstract class BaseItem : EntityData
{
public string Owner { get; set; }
public string Text { get; set; }
}
How do I ensure that the Owner and Text are indexed?
Update. I think I can add [Index(IsClustered = false)]
Use standard Entity Framework semantics.
public class BaseItem : EntityData
{
[Required]
[Index]
public string Owner { get; set; }
}
For more information, see http://www.entityframeworktutorial.net/code-first/dataannotation-in-code-first.aspx
Related
How to make optional REQUIRED for the same attribute on different inherited classes on EF6.
Why the 'required attribute' from one child is required for other child?
Why does entity framework merge all data anotations to base classe 'Person' if the base class is non required attributes?
I've used the same classes on MVC to create required fields on cshtml, and it works. The MVC understands only required field from one child and not make any 'wrong merge' with those two child classes.
For example:
//EF Codefirst Class
public class Person
{
[Key]
public int key{get;set;}
[StringLength(500)]
public virtual string name { get; set; }
[StringLength(500)]
public virtual string email{ get; set; }
[StringLength(500)]
public virtual string phone{ get; set; }
[StringLength(500)]
public virtual string address{ get; set; }
[StringLength(500)]
public virtual string manager{ get; set; }
[StringLength(500)]
public virtual string Discriminator{ get; set; }
}
//My Inherited classes
public class Employee : Person
{
[Required]
public override string name{ get; set; }
[Required]
public override string phone{ get; set; }
[Required]
public override string manager{ get; set; }
}
public class Manager: Person
{
[Required]
public override string name{ get; set; }
[Required]
public override string email{ get; set; }
}
//And my sample function 'Add PersonManager'
private void InsertPerson()
{
using (var ctx = new MyDataContext())
{
try
{
var m = new Manager() ;
m.name = "my name" ;
m.email = "my#email.com";
m.address =" something";
ctx.Person.Add(m);
ctx.SaveChanges();
}
catch (Exception ex)
{
// Why, if I try to Add my Person 'Manager', the attribute : phone and manager is REQUIRED?
}
}
}
It happens because you are using TPH strategy. All entities will be merged in one table, EF handles what must be null or not null.
If you use TPT strategy, EF will create different tables for each entity. To learn more about inheritance strategies take a look at this link http://blogs.msdn.com/b/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx
To use TPT instead of TPH, you must define a "key" in your child class, like this:
public class Employee : Person
{
[Key]
public int employeeId;
[Required]
public override string name;
[Required]
public override string phone;
[Required]
public override string manager;
}
Another way to do this is using Fluent API. Like this:
modelBuilder.Entity<Person>()
.HasKey(c => c.key);
modelBuilder.Entity<Employee>()
.ToTable("Employees");
modelBuilder.Entity<Manager>()
.ToTable("Managers");
To see more about this, take a look at this link https://msdn.microsoft.com/en-us/data/jj591617.aspx#2.5
I have class with this definition :
public class WebSiteContent
{
public Guid Id { get; set; }
public About About { get; set; }
public Tips Tips { get; set; }
public Images Images { get; set; }
}
where my About and Tips and Images are look like this :
public class About
{
public Guid Id { get; set; }
public string Text { get; set; }
public string Addres { get; set; }
public int PhoneNumber { get; set; }
public int Mobile { get; set; }
}
and Tips :
public class Tips
{
public Guid Guid { get; set; }
public string Content { get; set; }
}
and Images :
public class Images
{
public Guid Id { get; set; }
public string Background { get; set; }
public string Logo { get; set; }
public About About { get; set; }
}
here i just want to use about and Images and tips as a helper class to just create a property and don't want to have about,Images or tips table in database !
Entity framework needs Id to map all of above classes , how can I do that ?
here i just want to use about and Images and tips as a helper class to
just create a property and don't want to have about,Images or tips
table in database
So you are looking for complex type. Mark your About, Tips and Images classes with [ComplexType] attribute.
Entity framework needs Id to map all of above classes , how can I do
that ?
EF only needs Id for entities. If you map them as complex types you will not need to use any Id.
Btw. if you don't want to have those classes and their properties in database at all you can use [NotMapped] attribute instead.
I got the result from the collection in MongoDB, the structure is the same as below
[DataContract]
public class Father
{
[BsonId]
[DataMember]
public MongoDB.Bson.ObjectId _id { get; set; }
[DataMember]
public string Id { get; set; }
[DataMember]
public List<Child> childs { get; set; }
}
[DataContract]
public class Child
{
[DataMember]
public string Id { get; set; }
[DataMember]
public int Name { get; set; }
}
When I try this:
List<Father> f = result.ToList();
It calls Element 'Id' does not match any field or property of the class Model.Child
I think it just takes 'Id' as something else.
How can I deal with it? Thank you
You can resolve the issue by adding [BsonIgnoreExtraElements] on top of the class declaration. ObjectId is internally maintained by MongoDB which may not be needed unless you want to get additional information such as timestamp from the object. Hope this helps.
var conventionPack = new ConventionPack { new IgnoreExtraElementsConvention(true) };
ConventionRegistry.Register("IgnoreExtraElements", conventionPack, type => true);
This works just perfectly!
[BsonIgnoreExtraElements] also worked well, but, if you want to add any other ConventionRegistry like CamelCaseElementNameConvention, then, it overrides the Attribute one and the same exception occurs. Not sure if that could also be achieved using some other attribute.
I was using a dynamic list (List) to build a filter and was receiving a similar error. I added these lines to my data class to fix the problem.
[BsonId]
public ObjectId Id { get; set; }
this work for my case: add the attribute
[DataMember]
[BsonElement("songName")]
onto the elements:
[BsonIgnoreExtraElements]
public class Music
{
[BsonId]
[DataMember]
public MongoDB.Bson.ObjectId _id { get; set; }
[DataMember]
public string Id { get; set; }
[DataMember]
[BsonElement("songName")]
public string SongName { get; set; }
[DataMember]
[BsonElement("artistName")]
public string ArtistName { get; set; }}
I faced to same problem.Same error occured at var data = query.ToList();
var collection = db.GetCollection<Product>("Products");
var query =
from e in collection.AsQueryable<Product>()
where e.name == "kalem"
select e;
var data = query.ToList();
and my insert was this:
var collection = db.GetCollection<Product>("Products");
collection.InsertBatch(products);
I solved as below.
ObjectId id = new ObjectId();
var collection = db.GetCollection<Product>("Products");
collection.InsertBatch(products);
id = pr.Id;
and I added id to Product class as below
Product Class
class Product
{
public ObjectId Id { get; set; }
public string name { get; set; }
public string category { get; set; }
public double price { get; set; }
public DateTime enterTime { get; set; }
}
you can use BsonNoId attribute
[DataContract]
[BsonNoId]
public class Child
{
[DataMember]
public string Id { get; set; }
[DataMember]
public int Name { get; set; }
}
just add this in the top of the class
[BsonIgnoreExtraElements]
all you have to do is removing the [DataMember] on the ObjecId attribute and bind the Id to the ObjectId _id.
so your class should look like this :
[DataContract]
public class Father
{
[BsonId]
public MongoDB.Bson.ObjectId _id { get; set; }
[DataMember]
public string Id {
get { return _id.ToString(); }
set { _id = ObjectId.Parse(value); }
}
[DataMember]
public List<Child> childs { get; set; }
}
ps : in your case the child id must be generated manually, if you want it to be an objectId(mongo), you will have do the same trick
finally, to deserialized the object, you should use the newtonsoft.json reference and do like this
Father = JsonConvert.DeserializeObject<Father>(response.Content);
Your Child class should probably specify it inherits Father
public class Child: Father { ... }
Your Father class should probably add known type attribute (for WCF ).
[DataContract]
[KnownType(typeof(Child))]
public class Father
If this is a MongoCollection("fathers") that you save / fetch through, then you may need to register a class map for each expected child type.
if (!BsonClassMap.IsClassMapRegistered(typeof(Child)))
{
BsonClassMap.RegisterClassMap<Child>(
cm => { cm.AutoMap(); });
}
As #alexjamesbrown mentioned, you are not required to name the id field on your poco object '_id'.
The idea with inheritance is to inherit. So using the Father's "id" field (whatever it is named) should suffice. It's not clear why your Father class has both Id and _id properties. One of them is probably not necessary.
//here is my data models:
public class People
{
public int PeopleID { get; set; }
[Required]
public string Name { get; set; }
}
[Table("User")]
public class User : People
{
[Required]
public string LoginName { get; set; }
[Required]
public string PassWord { get; set; }
}
//and i stored an item into the People table
context.People.Add(new People { Name = "Jack" });
context.SaveChanges();
//and now "Jack" is promoted as an user of this system
//how can I update his data and let him has is LoginName and Password?
This is a common design mistake.
Objects can't change their type; you shouldn't be using inheritance in this case.
Instead, the User can have a reference to a Person (another hint: your entity names should be singular, regardless of what you name the table)
First of all you need to declare discriminator column. For example PeopleType which couln't discriminate users from all peolple by specific value.
So in your scenatio you will need to create Jack as User but you could assecc it as item of people
[Table("People")]
public class People
{
public int PeopleID { get; set; }
[Required]
public string Name { get; set; }
public int Type { get; set; }
}
public class User : People
{
[Required]
public string LoginName { get; set; }
[Required]
public string PassWord { get; set; }
}
Overide it in DbContext
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<People>().Map<User>(m => { m.Requires("PoepleType").HasValue(1 /* any value you like */); })
}
This is my model class.
public class Lead
{
private readonly ObservableCollection<String> m_tags = new ObservableCollection<string>();
public int LeadId { get; set; }
public string Title { get; set; }
public ObservableCollection<String> Tags { get { return m_tags; } }
}
Does Entity Framework offer a way to represent this using either Model-First or Code-First?
EDIT: I'm looking for a way to do this without changing the public API of the model. The fact that there is some sort of Tags table shouldn't be visible to the downstream developer.
Since your model has to be represented in a relational way, you can only use primitive types (that have an equivalent in a SQL DB) or other entities within a entity definition - that means the tags are represented by their own entity. In your case it would be something like this using Code first approach:
public class Lead
{
public int LeadId { get; set; }
public string Name { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
public class Tag
{
public int TagId { get; set; }
public string Name { get; set; }
}
public class SomeContext : DbContext
{
public DbSet<Lead> Leads { get; set; }
public DbSet<Tag> Tags { get; set; }
}
This (by default) will be represented in the database as a table Leads, a table Tags, and a relationship table LeadTags that only contains {LeadId, TagId} pairs.