I have exposed some EF5.0 entities generated from a database through at WCF data service.
The data service is consumed by a WPF-client which takes the entities (from the data service) and store them locally. I do this by creating a code-first entity database based on the WCF-entities:
public class LocalRaceContext : DbContext
{
public LocalRaceContext() { }
public LocalRaceContext(string connstr) : base(connstr) { }
public DbSet<Participant> Participants { get; set; }
.
.
. more ...
}
I want to extend the Participant with a new property (in the client-side model). I figured I could just do this with a partial class like so:
public partial class Participant
{
public virtual List<Stamp> Stamps { get; set; }
}
This however does not work. Do I need some kind of attribute on the partial class?
I get the following error:
"The type 'RaceEntities+Participant' was not mapped. Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive, nested or generic, and does not inherit from EntityObject."
Edit:
#IronMan84: The original model (without the partial class) works because EF code-first takes care of the database and table creation. Actually it works perfectly fine and I am able to save the EF model in a local SQL CE file and retrieve the objects again as EF-classes later.
What I'm trying to achieve is to persist data from the data service locally but in a model which is somewhat extended. I've succeeded so far up until the extending part.
#Matt Whetton: It fails when I create a new instance of LocalRaceContext.
Edit2: I've tried to make an empty partial class (no properties). It still throws the same error.
Thanks in advance
Frederik
Nested classes are not yet supported by EF. Move the Participant class outside of RaceEntities.
Related
Hello i am trying to use derived classes using EF Core using a single concrete table containing the reunion of the derived types.
public abstract A
{
public int Id{get;set;}
}
public B:A
{
public string Name{get;set;}
}
public C:A
{
public bool IsMan{get;set;}
}
public class MyContext:DBContext
{
public DBSet<A> ATable {get;set;}
}
When the database gets generated the Table ATable does not contain the fields of the C subtype.The resulting table contains only A-s fields and B-s.
Generated table
Id
Name
P.S Do i need to use some kind of discriminator ? I just want one table that has the reunion of the two subtypes , and to be able to access it using OfType Linq extension.
What you are describing is called TPH (Table per Hierarchy) inheritance strategy and currently is the only supported pattern by EF Core.
However, unlike EF6 EF Core does not automatically detect the derived entities by reflecting the model assembly. This was causing unexpected side effects in EF6, hence has been removed and now you are required to explicitly include derived types in the model (if not included by other mechanisms like navigation properties or explicit DbSets). This is explained in Entity type hierarchy mapping section of EF Core documentation:
By convention, EF will not automatically scan for base or derived types; this means that if you want a CLR type in your hierarchy to be mapped, you must explicitly specify that type on your model. For example, specifying only the base type of a hierarchy will not cause EF Core to implicitly include all of its sub-types.
So, the minimum you need to get TPH with your sample model is either adding
public DbSet<B> Bs { get; set; }
public DbSet<C> Cs { get; set; }
or Entity fluent API:
modelBuilder.Entity<B>();
modelBuilder.Entity<C>();
I'm wondering if there is any way to map a stored procedure result into into a class.
This is what I have:
// DbContext Class:
public DbSet<StoredProcedureModelResult> SPMR { get; set; }
// Service Class:
var result = ctx.Set<StoredProcedureModelResult>().FromSql("getXXXX p1 = {0},1).ToList();
This works well, however, I'm using database migrations and every time I add one this thing creates StoredProcedureModelResult as a table...
I tried to ignore it onModelCreating:
modelBuilder.Ignore<SPModels.test>();
but this throws an exception:
Cannot create a DbSet for 'StoredProcedureModelResult ' because this type is not included in the model for the context
I just want use the benefit of mapping, and not to get a table creation, this is a simple model (non-entityType)
BTW
.NET Core 1.1
Web API
EF Core (code-first)
Thank you
You don't need to make the type an Entity type (by registering a DbSet in your DbContext). Just have a method that returns IEnumerable<StoredProcResults> (can be in your DbContext), and in it run
dbContext.Database.SqlQuery<StoredProcResults>(...)
See Database.SqlQuery<T>(...)
Since I already have a DB project in my solution, I was wondering can I leverage Entity Framework so that the Web Application may communicate with the database without having to do any migrations, or is migration necessary in order to use the Context of Entity Framework?
If migrating is not necessary then I also won't need the designer (edmx) file, I could just make my models and link them into my context right?
Not necessary at all.
I often write short solutions towards some databases where I just want to add some functionality on the fly. What I typically do is to just open SQL Server Object Explorer in VS2015, Expand the table I'm interested in, and just write a class on the fly, matching the fields that I need.
I.e for a table named "Classes" in the database, I would end up with a class in C#
public class SomeClass
{
public int Id {get; set;}
public string Title {get; set;}
// +other intersting fields
}
Then I simply create a DbContext class pointing to my database:
public class MyContext : DbContext
{
public DbSet<SomeClass> Classes{get; set;}
public MyContext() : base("myConnectionString"){}
}
That's it. No need for migrations. It then simply just works :)
I am using EF 4.3 and am adding Audit fields to my classes and tables. I have a service layer which is getting the credentials of the client applications by using the OperationContext, so I am passing that information to my tables through EF mappings. An example of this would be:
class A
{
string CreatedByUser { get; set; }
}
class B : A
{
}
I am using the fluent interface to provide my POCO to table mappings -- when I map the CreatedByUser column in the base and derived class, the derived class mappings do not take effect and the information is not passed to the database.
I have gotten around this by creating fields in my base class for the derived classes to use that are just pass-throughs of the audit columns but this is messy.
Try making class A abstract, I think that will give you the effect you are looking for(add the columns from class A to all class/tables that inherit it)
I have a project where the client is using Entity Framework, and I'm trying to abstract away the generated classes from the rest of the application.
One generated class is Category and it has say Type as a property.
I've created an interface that I want Category to implement, like this:
public interface ICategory
{
string Type { get; set;}
}
I have done this in LINQ to SQL before and it works fine. I create a partial class in a separate file and have it implement the interface:
public partial class Category: ICategory
//implement interface
However, with EF whenever I try to build a query with EF it says it doesn't support OfType<>().
Example:
var query = from c in DataContext.Category
where Type == "some type"
select c;
var resultsList = query.OfType<ICategory>(); //error here (not supported)
What am I doing wrong here?
Other things to note: I'm developing this in a silverlight application and the data context is actually being pulled from a service, so there's a client server relationship going on here as well.
As a general rule, LINQ to Entities can only understand things which are part of your entity model (EDMX). So while you are free to extend your entity types be a partial classes, you cannot use properties, methods, and interface references you add there in LINQ to Entities queries, except for certain, very specific features.
However, in this case the following query should give you the result you want:
var resultsList = query.Select<ICategory>(c => c);