I have a table Test with a foreign key to itself. In metadata class I have
[Include]
Test Test2 { get; set; }
In a service class:
return this.ObjectContext.Test.Include("Test2")
I checked that data loaded correctly from database. But on a client side I see that no parent has been loaded.
I use a DomainDataSource to load data (Silverlight 4.0).
Someone else experienced this strange behavior?
Ok, my mistake. The answer is to use [Include] attribute as always, but make sure that all participating properties are public in your metadata class.
Related
I use database first. In the auto-generated EF5 code:
Account has ClientID(FK)
Client has AddressID(FK)
Address has public List<EFClient> Clients { get; set; } (i did not specify this in DB but ef5 auto generated it)
When I serialize Address object, it throws exception "there is a circular reference" because the client collection in the address also cotains same address again
What can I do in this situation?
How can I not let EF5 auto-generate that Clients collection?
Thanks in advance!
I don't think you actually want to stop EF from auto-generating this navigation property, as it will affect lots of places. What you can do is simply remove the property that it generated from the model, which will remove the property from the class.
I am using Entity Framework on a project, but am finding the large queries, especially those which use LEFT joins, to be very tedious to write, and hard to debug.
Is it common, or accepted practice, to make use of Views in the database, and then use those views within the EntityFramework? Or is this a bad practice?
the question is not very clear but there is no absolute right or wrong in Software. it all depends on your case.
there is native support for views in ef core but there is no native support for views in EF < 6. at least not in the current latest version 6.3. there is, however, a work around to this. in database first you would create your view via sql normally and when you reverse engineer your database, EF will treat your view as a normal model and will allow you to consume it regularly as you would do in a normal table scenario. in Code First it's a bit more tedious. you would create a POCO object that maps to the columns in your view. notice that you need to include an Id in this POCO class. for example
public class ViewPOCO
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id {get;set;}
public string ViewColumn1 {get;set;}
... etc.
}
you would add this POCO class in your DbContext
public class MyDbContext : DbContext
{
public virtual DbSet<ViewPOCO> MyView {get;set;}
}
now you will normally apply the command of adding migration through the package manager console
Add-Migration <MigrationName> <ConnectionString and provider Name>
now in the migration up and down you will notice that EF treats your Model as table. you would clear all of this and write your own sql to add/alter the view in the up and drop the view in the down method using the Sql function.
public override void Up()
{
Sql("CREATE OR ALTER VIEW <ViewName> AS SELECT NEWID() AS Id, ...");
}
public override void Down()
{
Sql("DROP VIEW <ViewName>");
}
First create your view.
Update Your .edmx File.
then use like this.
using (ManishTempEntities obj = new ManishTempEntities())
{
var a = obj.View_1.ToList();
}
I need to design domain that has two simple entities:
public class User
{
public virtual int Id { get; protected set; }
public virtual string Email { get; protected set; }
public virtual Country Country { get; protected set; }
...
}
public class Country
{
public virtual int Id { get; protected set; }
public virtual string Name { get; protected set; }
...
}
It's all nice and clear in domain world but the problem is that User and Country persisted in two different databases on two different servers (tho they are both MSSQL 2005 servers).
So, how should I correctly implement persistance of entites across different sql servers in NHibernate?
Using IDs instead of objects in references? Yeah, thats simple but it's hitting hard on the whole domain thing making domain object more like DTO. And it will require that IUserRepository get it's hands on ICountryRepository to load User entity.
Linked servers? Hm... Somehow I don't like it (distributed transactions and no XML columns). And what I should be aware in case of using them and more importantly how should I configure NHibernate to work effectively with linked servers?
Maybe some other solution?
I've heard of people using the schema property in a class mapping to contain the linked server name (like otherserver.dbo), but I don't know anyone that hasn't ran into one problem or another when doing that.
There are a few DDD bootstrapping frameworks that allow you to transparently map entities to different databases (resulting in multiple ISessionFactories, which it will manage for you). NCommon is one I would recommend. This assumes, however, that Country only exists in one database, and User only exists in another.
As for transactions... well, if you use a TransactionScope and configure DTS, that might work. NCommon uses a UnitOfWork API that also wraps TransactionScope.
You would have to change User so that Country is just an ID. Here's why. You'd end up with two session factories, one that has a mapping for Country and the other that has a mapping for User. If you don't make that change, NHibernate will complain that there is no mapping for Country when you save User (since they are stored in two different DBs).
Now you could instruct NHibernate to ignore Country property, and keep Country so your domain doesn't change. However, when you load User from the database next time, Country will be null.
You could use NHibernate.Shards from NHContrib.
Using silverlight 4, with RIA Services Toolkit May 2010.
I have an Entity Data Model (.edmx) which contains a FK reference.
In my DomainContext Service class (which references my .edmx) I modified my GET method to include Include("FK_ENTITY_TABLE_NAME"):
public IQueryable<PARENT_ENTITY> GetPARENT_ENTITY()
{
this.ObjectContext.PARENT_ENTITY.Include("FK_ENTITY_TABLE_NAME");
}
In my DomainContext Service Metadata class (.metadata.cs) named "internal sealed class PARENT_ENTITYMetadata" I added the [Include] attribute to the
property which references my FK entity:
[Include]
public FK_ENTITY_TABLE_NAME { get; set; }
My generated (.g.cs) ria service proxy file contains the following DataContract with XmlIgnore:
private EntityRef<FK_ENTITY_TABLE_NAME_PARENT_ENTITY> _fk_entity_table_name;
public sealed partial class PARENT_ENTITY : Entity
{
...
[Association("FK_ENTITY_TABLE_NAME_PARENT_ENTITY", "entity_id", ",entity_id", IsForeignKey=true)]
[XmlIgnore()]
public FK_ENTITY_TABLE_NAME FK_ENTITY_TABLE_NAME
{
...
Therefore, when I use the XmlSerializer / DataContractSerializer and on my PARENT_ENTITY, it skips right over serializing my "FK_ENTITY_TABLE_NAME entity:
<PARENT_ENTITY>
(note: no FK_ENTITY_TABLE_NAME serialized here)
</PARENT_ENTITY>
Is there anything i can do to control the XmlIgnore attribute from being inserted in these generated files?
I'd suggest first off to fix your naming convention. Other than that make sure that you expose a get method for your DATA_ENTITY class so that it gets compiled into the generated code.
Also, why is your include for FK_ENTITY_TABLE_NAME but the entity class uses DATA_ENTITY? That seems strange to me. Is there any other relevant code you haven't included?
I am working on a silverlight application and I am using RIA data services and nHibernate.
Currently, I have an entity with a one to many relationship to another entity.
public class Employer {
[Key]
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class Person {
[Key]
public virtual int Id { get; set; }
public virtual string Name { get; set; }
[Include]
[Association("PersonCurrentEmployer", "CurrentEmployerId", "Id", IsForeignKey = true)]
public virtual Employer CurrentEmployer { get; set; }
public virtual int? CurrentEmployerId { get; set; }
}
The property CurrentEmployerId is set for no insert and no update in the mappings.
On the Silverlight side, I set the CurrentEmployer property of the person to an existing employer on the client side submit the changes.
personEntity.CurrentEmployer = megaEmployer;
dataContext.SubmitChanges();
On the server side, the person entity's CurrentEmployerId is set to megaEmployer.Id but the CurrentEmployer is null. Because I am using the CurrentEmployer property and not the CurrentEmployerId to save the relationship, the relationship isn't changed.
Is there a way to force RIA to send the CurrentEmployer object with the save or do I have to use the CurrentEmployerId on the server side to load the employer and set it to the CurrentEmployer?
The reason you're not seeing your CurrentEmployer on the client side is because you don't have your association setup correctly.
RIA services doesn't work with references in the usual way so referencing your Employer on the client side doesnt work. RIA services works with entity sets and creates the "references" based on the association attributes. Your employer needs a property with an association back to the Person as follows.
public class Employer
{
private Person person;
[Key]
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual int PersonID { get; set; }
[Include]
[Association("PersonCurrentEmployer", "PersonID", "Id", IsForeignKey = false)]
public virtual Person Person {
get
{
return this.person;
}
set
{
this.person = value;
if (value != null)
{
this.PersonID = value.Id;
}
}
}
}
Is there a way to force RIA to send the CurrentEmployer object with the save or do I have to use the CurrentEmployerId on the server side to load the employer and set it to the CurrentEmployer?
I'm running into this problem as well. Basically, you either have to use the [Composition] attribute (which I wouldnt' recommend), or load the entity from the database, server-side. Composition muddies up the client data model and doesn't take care of all cases you need to worry about. (there is a lot more on Composition in the RIA forums.silverlight.net)
[UPDATE] Once you implement 2nd level cache, the worry of reading supporting entities from the database mostly goes away, as they will be loaded from cache. Also, if you only need a proxy for NHibernate to not complain, then look into Get/Load (can never remember which) .. which will return an NH proxy and will result in a single-column-and-entity select from the database. (If you try to access another property of the proxy, NH will select the rest. you can find more on this on Ayende's blog..)[/UPDATE]
The biggest problem I'm having is getting NHib to actually save and load the relationship. (I'm also using Fluent). The response from the responsible parties has so far been "waah, you can't do that. it looks like RIA wasn't developed with NHib in mind" .. which is a crap answer, IMHO. Instead of helping me figure out how to map it, they're telling me i'm doing it wrong for having a ForeignKey in my entity (NHib shouldn't care that i have my FK in my entity) ...
I want to share what I did to make this work, because 'official' support for this scenario was ... let's just say unhelpful at best, and downright rude at worst.
Incidentally, you had the same idea I had: making the Foreign Key not insert/update. BUT, I've also made it Generated.Always(). this way it will always read the value back.
Additionally, I override DomainService.Submit() and DomainService.ExecuteChangeSet(). I start an NHibernate Transaction in the Submit (though I'm not yet sure this does what I expect it does).
Instead of putting my save logic in the InsertSomeEntity() or UpdateSomeEntity() methods, I'm doing it all inside ExecuteChangeSet. this is because of NHibernate, and its NEED to have the entity graph fully-bi-directional and hydrated out prior to performing actions in NHibernate. This includes loading of entities from the database or session when a child item comes across the wire from RIA services. (I started down the path of writing methods to get the various other pieces of the graph as those specialized methods needed them, but I found it easier to do it all in a single method. Moreover, I was running into the problem of RIA wanting me to perform the insert/updates against the child objects first, which for new items is a problem.)
I want to make a comment about the composition attribute. I still stand by my previous comment about not recommending it for standard child entity collections, HOWEVER, it works GREAT for supporting NHibernate Components, because otherwise RIA will never send back the parent instance (of the composition), which is required for NHibernate to work right.
I didn't provide any code here because i would have to do some heavy redacting, but it's not a problem for me to do if you would like to see it.