Environment:
Breeze 1.4.16
Durandal 2.1.0
EF 6.1.1
Consider the following classes Account, Activity, and User. Let's call it a simple CRM scenario where a user creates sales activities for an account in their portfolio.
public class Account
{
public int Id {get; set;}
public ICollection<Activity> Activities {get; set;}
}
public class Activity
{
public int Id {get; set;}
public DateTime ActivityDate {get; set;}
public int AccountId {get; set;}
[ForeignKey("AccountId")]
public Account Account {get; set;}
public int CreatedById {get; set;}
[ForeignKey("CreatedById ")]
public User CreatedBy {get; set;}
}
public class User
{
public int Id {get; set;}
public string Name {get; set;}
}
I'm struggling to write a breeze query which when retrieving an Account, expands the related Activity entity to give me the Name of the user who entered the activity.
The following query works, however the createdBy property of each activity entity is always null:
var query = breeze.EntityQuery
.from("getAccount")
.withParameters({ id: id })
.expand("Activities");
Reading through the breeze documentation on Navigation Properties at: http://www.breezejs.com/documentation/navigation-properties, this seems close to the "OrderDetails.Product" scenario so I rewrote the query as follows:
This query throws an exception when I execute it.
var query = breeze.EntityQuery
.from("getAccount")
.withParameters({ id: id })
.expand("Activities.CreatedBy");
Related
I just want to confirm whether this is a good approach to model an entity as bellow and what are the basics rules that it brakes?
By doing so do I need to do anything OnModelCreating?
Usecase: There are two types of users. One is Manger, the other one is the Marketing Officer. Then the Manager wants to create his team.
So I have modeled it as follows.
User and Role entities
public class User {
public int Id {get; set;}
public string UserName {get; set;}
public virtual Role Designation {get; set;}
}
public class Role {
public int Id {get; set;}
public string RoleName {get; set;}
}
Then composed the Team entity.
public class Team {
public int Id {get; set;}
public int ManagerId {get; set;}
public virtual User Manager {get; set;}
public virtual ICollection<User> MarketingOfficers {get; set;}
}
I am using Entity Framework code first to design the database.
I have 2 models with One to Many relationship. One "Foo" can have many "FooData" as follows -
public class Foo {
[Key]
public string serialNumber{get; set;}
public int someNumber {get; set;}
public string someName {get; set;}
// Many more properties
// Navigation Collection
public virtual ICollection<FooData> FooDatas{get; set;}
}
public class FooData{
[Key]
[ForeignKey("foo")]
public string SerialNum {get; set;}
public DateTime SomeTime {get; set;}
public byte[] SomeData {get; set;}
// Navigation property
public virtual Foo foo {get; set;}
}
When I try to add a controller for "Foo" in MVC, using "Foo" as a scaffolding model, it gives me this error - "Multiplicity is not valid in Role. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be 1".
I would appreciate some help here.
Thank you
Because of how you have it defined the same key is used in both so it is a 1-to-1 relationship. If you want a real one to many you will need to add/create another field and set them up as a composite key on the FooData table/entity.
public class Foo {
[Key]
public string serialNumber{get; set;}
public virtual ICollection<FooData> FooDatas{get; set;}
}
public class FooData {
[Key, Column(Order = 0),ForeignKey("foo")]
public string SerialNum {get; set;}
[Key,Column(Order=1)]
public int DataId {get;set;}
public virtual Foo foo {get; set;}
}
Which is the best way to model multiple one-to-one relationships to a same table (sqlite-net-extensions)? I am looking for a solution like this:
Class WayBill
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
[ForeignKey(typeof(Organization ))]
public int ConsignerId {get; set;}
[OneToOne]
public Organization Consigner {get; set;}
[ForeignKey(typeof(Organization ))]
public int ConsigneeId {get; set;}
[OneToOne]
public Organization Consignee {get; set;}
}
Class Organization
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
public string Name {get; set;}
}
Obviously, the above won't work.
I have considered other options too:
create a table (WayBillOrganization) that captures the role of organization:
Waybill -->> WayBillOrganization --> Organization
put the required inverse OneToMany properties in to the Organization.
Handle things manually (ie. store only primary keys in the WayBill class and load the Organizations separately).
Option 2. is something I want to avoid. Organizations are related to so many other classes (not in my example) and even in the case of a waybill, there's a few more relationships I didn't include into the example (carrier, cargo paying party, freight forwarder and so on). Besides, I'd rather use inverse properties only when I need to navigate (for example, I don't use organization to find waybills, so an inverse property is only an extra burden.)
Option 3. isn't that attractive either.
So the option 1. seems to be the way to go. But before going there, I'd like to know if the perfect-world solution in my example is indeed impossible.
So, my question is: Is there a way to model multiple one directional OneToOne relationships without explicitly declared inverse properties?
Your use case is supported in SQLite-Net Extensions. You only have to specify the foreign keys explicitly in the relationship attributes, because automatic discovery may not work as expected:
class WayBill
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
public int ConsignerId {get; set;}
[OneToOne("ConsignerId")]
public Organization Consigner {get; set;}
public int ConsigneeId {get; set;}
[OneToOne("ConsigneeId")]
public Organization Consignee {get; set;}
}
class Organization
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
public string Name {get; set;}
}
Inverse relationships to the same class are also supported, but must be also declared explicitly at both ends:
class WayBill
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
public int ConsignerId {get; set;}
[OneToOne(foreignKey: "ConsignerId", inverseProperty: "ConsignerInverse")]
public Organization Consigner {get; set;}
public int ConsigneeId {get; set;}
[OneToOne(foreignKey: "ConsigneeId", inverseProperty: "ConsigneeInverse")]
public Organization Consignee {get; set;}
}
class Organization
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
public string Name {get; set;}
[OneToOne(foreignKey: "ConsigneeId", inverseProperty: "Consignee")]
public WayBill ConsigneeInverse { get; set; }
[OneToOne(foreignKey: "ConsignerId", inverseProperty: "Consigner")]
public WayBill ConsignerInverse { get; set; }
}
I have a table with 9 columns in database and I want to be able to load only some fields of it if I need.
How can I do this with Entity Framework 4 please?
e.g. My table has these fields:
ID, FirstName, LastName, FotherName, BirthDate, Mobile, Email
and I want to be able to fetch just these columns:
ID, FirstName, LastName
My project is an ASP.NET MVC 3 application, with SQLServer 2008 Express and EF 4.1.
Assume you have a table with this model:
public class User{
public int ID {get; set;}
public string NickName {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string FotherName {get; set;}
public DateTime BirthDate {get; set;}
public string Mobile {get; set;}
public string Email {get; set;}
public string Password {get; set;}
}
Now, you want fetch just ID, FirstName, LastName, and FotherName. You can do it in 2 way; The first way is fetch them as an anonymous object, look:
var user = entityContext.Users.Where(u => u.ID == id)
.Select(u => new {
ID = u.ID,
FirstName = u.FirstName,
LastName = u.LastName,
FotherName = u.FotherName
}).Single();
Now, your return-value-type is anonymous, you can work with it such as:
var i = user.ID;
// or
var s = user.FirstName;
In another way (for example when you want to pass the object as an Model to a View), you can define a new class, (i.e. UserViewModel), and when you select the object, select it as a UserViewModel. look:
public class UserViewModel{
public int ID {get; set;}
public string NickName {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string FotherName {get; set;}
}
and in query, take this:
var user = entityContext.Users.Where(u => u.ID == id)
.Select(u => new UserViewModel {
ID = u.ID,
FirstName = u.FirstName,
LastName = u.LastName,
FotherName = u.FotherName
}).Single();
Look that just ONE difference is between them, in labda expression, instead of u => new {}
we are using u => new UserViewModel{}. Good luck.
There can be many ways to do this job, but using Automapper NuGet package is the most simple one I have experienced.
First: Install Autmapper NuGet package for your project from NuGet package explorer.
Second: Make a simple ViewModel, which contains only required attributes:
public class UserViewModel {
public int ID {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
}
Third: Initialize your your mapper only for once in app_start class like:
namespace SampleProject.App_Start {
public class AutoMapperConfig {
public static void Initializer() {
AutoMapper.Mapper.Initialize(cfg => {
cfg.CreateMap<User, UserViewModel>()
});
}
}
}
Fourth: Add it's entry in Global.asax.cs:
namespace SampleProject
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// AutoMapper Initializer
App_Start.AutoMapperConfig.Initializer();
}
}
}
Fifth: Use it in your controller where you want like this:
namespace SampleProject.Controllers
{
public class UsersController : Controller
{
private DataContext db = new DataContext();
public ActionResult Index()(
var model = AutoMapper.Mapper.Map<List<UserViewModel>>(db.User.ToList());
return View(model);
}
}
}
Last: You can create as many maps as you want between your Models and ViewModels by initializing them once in the app_start's AutoMapperConfig class and use them where you want with a simple line of code.
Also you can find a lot of help about Automapper if you search about it. Its main website is here.
Important:
I am a developer of ASP.NET MVC 5. Automapper works fine for me every time. I cannot check it on MVC 3 or older than MVC 5.
I am using EF 4.1 and POCO model (code only).
I have a Fiche entity which has Id as the primary key.
And FicheCancellation entity, which has a Id which holds the Id of the Fiche that is cancelled and a CancellationFicheId which holds the Id of the generated cancellation Fiche's Id
class Fiche {
public Guid Id {get; set;}
...
public virtual Fiche CancelledFiche {get; set;}
public virtual Fiche CancellationFiche {get; set;}
public virtual FicheCancellation Cancellation {get; set;}
}
class FicheCancellation {
// cancelled FicheId
public Guid CancelledFicheId {get; set;}
//generated cancellation ficheId
public Guid CancellationFicheId {get; set;}
public virtual Fiche CancelledFiche {get; set;}
public virtual Fiche CancellationFiche {get; set;}
....
some other fields about the operation
...
}
now how do I configure navigations above, either with ForeignKey attributes or with ModelBuilder;
1- so that I have access to the cancellation entity.
2- and if the Fiche entity is a cancellation fiche, have a reference to the cancelled fiche.