entity framework navigation property to table in different db - entity-framework

I have 2 tables in different db
db1..Towns
id
Nazv
db2..MathchedTown
id
t_id
d_name
They are joined by по Towns.id = MathchedTown.t_id
This EF classes:
[Table("Towns")]
public class Town
{
[Key]
public int id { get; set; }
public string Nazv { get; set; }
}
[Table("MathchedTown")]
public class mTown
{
[Key]
public int id { get; set; }
[Required]
public string t_id{ get; set; }
[Required]
public string d_name{ get; set; }
[ForeignKey("t_id")]
public virtual Town town { get; set; }
}
when i try to get item.town.nazv i get error:
Invalid object name 'dbo.Towns'.
If i change [Table("Towns")] to [Table("db1.dbo.Towns")], then appear almost the same error: Invalid object name 'dbo.db1.dbo.Towns'.
That all errors are SqlExceptions
How i can talk EF4 don't substite the "dbo." prefix?

Entity framework does not support multiple databases in a single context. But it supports multiple schemas in a single database. If you do not specify the schema it will assume dbo.
[Table("Towns", "MySchema")]
public class Town
You can specify the schema as above.
If you want to use a table in a different database you can create a view to that table in your database. But it will be read only.

Unfortunately EF4 does not support navigation property that is in other db.
You have two choices.
One, create a stored procedure and import it as a function in edm. And genetate complex type for the return result.
Two, create two entity models for each database. And run a query for a database then run the other query to the other database with where clause from the first query result.

Related

Specify a Parent-Child relationship in EF Core without using identity columns

Specify a Parent-Child relationship in EF Core without using identity columns
What's an efficient way within Entity Framework Core 5 (C#) to work with the data in a hierarchial table that is linked via non-identity columns.
Here's my primary class:
public class ServiceProvider
{
[Key]
public int Id { get; set; }
public string ParentSPCode { get; set; }
public string SPCode { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ContactEmail { get; set; }
public string Status { get; set; }
}
The SPCode value is unique, which I enforce via C# code. The ParentSPCode may be null or must match an existing SPCode. Again I enforce this via C# code.
I want this table to hold any number of levels of parent-child (1 or more) records, as defined by ParentSPCode-SPCode pairs.
I can retrieve these records via a complex hierarchy of LINQ "joins", but I am thinking there must be a cleaner way by defining the appropriate EF Core 5 relationship.
If I was in SQL Server, I would do this via a CTE.
I want to be able to bring in the child records in a manner similar to .Include(q => q.ParentSPCode == x.SPCode).

Defining a "one-to-one-to-one" relationship on Firebird 2.5 EF Core

I'm working with EF Core and a third-party Firebird 2.5 database and, for some reason, they decided to, rather than do a simple one-to-one relationship, create a single table with two columns that do that relationship itself, i.e.
STOCK
========
ID_STOCK(int)
more columns (and their datatypes)
STOCK_IDENTIFIER
========
ID_STOCK (int)
ID_IDENTIFIER (int)
STOCK_PRODUCT
========
ID_IDENTIFIER (int)
more columns (and their datatypes)
So, every STOCK has one STOCK_IDENTIFIER, which, in turn, has one STOCK_PRODUCT. Usually, when I'm creating my own DB in MySQL, I just set foreign keys with data annotations (I'm not fluent in Fluent API, pun intended) and let the migration do its job. However, in this case I can't change the DB's schema (on the account of it being third-party), so I need to use the existing structure.
Right now I have the following:
public class STOCK
{
[Key]
public int ID_STOCK { get; set; }
[MaxLength(50)]
public string DESCRIPTION { get; set; }
[Column(TypeName = "decimal(18, 4)")]
public decimal SELL_PRICE { get; set; }
public STOCK_IDENTIFIER STOCK_IDENTIFIER{ get; set; }
}
public class STOCK_IDENTIFIER
{
[ForeignKey("ID_STOCK")]
public STOCK ID_STOCK { get; set; }
public STOCK_PRODUCT ID_PRODUCT { get; set; }
}
public class STOCK_PRODUCT
{
[ForeignKey("ID_PRODUCT")]
public STOCK_IDENTIFIER ID_IDENTIFIER{ get; set; }
[MaxLength(18)]
public string GTIN{ get; set; }
[MaxLength(18)]
public string SKU{ get; set; }
[Column(TypeName = "decimal(18, 4)")]
public decimal INSTOCK_AMNT { get; set; }
}
I read at The property X is of type Y which is not supported by current database provider that Fluent API could fix that, however, that article works flawlessly for one-to-one. As soon as I try to implement Fluent on a cascading relationship like this one, I get
modelBuilder.Entity<STOCK_IDENTIFIER>()
.HasOne<STOCK_PRODUCT>(p => p.ID_IDENTIFIER)
.WithOne();
modelBuilder.Entity<STOCK>()
.HasOne<STOCK_IDENTIFIER>(p => p.IDENTIFICADOR)
.WithOne();
The property or navigation 'ID_IDENTIFIER' cannot be added to the entity
type 'STOCK_PRODUCT' because a property or navigation with the
same name already exists on entity type 'STOCK_PRODUCT'.
Any hints on what I've been doing wrong?

Entity Framework Model with a max child record property

I have a couple of simple EF models with a parent child relationship. The children are essentially audit records. I am wanting to use the audits to get the min date to determine the "Create Date" of the parent.
The two models directly match the SQL Database as you would expect with the exception of the derived "CreatedDate" field that I was hoping for EF to translate into a simple "Max" subquery.
I am using the EF Repository Pattern with the Unit Of Work pattern and trying to keep things really simple with the SQL Server doing the MAX query.
I have tried using automapper to map in my service layer but this generates an SQL query per parent.
Any ideas?
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public virtual IEnumerable<Audit> Audits { get; set; }
//Read only create date and problem property
[NotMapped]
public DateTime CreatedDate
{
get
{
return Audits.Max(a => a.AuditDate);
}
}
}
public class Audit
{
public int Id { get; set; }
public int ItemId { get; set; }
public DateTime AuditDate { get; set; }
}
I could well be wrong but I don't think EF will support this; either you pull in all of the Audit records for an Item
e.g.
var item = _context.Items.Include("Audit").FirstOrDefault(i=>i.Id==1)
in which case the method will work.
Or, you could create a view mapped to a new entity (or QueryType if you are using EF Core) that contains Id, Name, and CreateDate only.
e.g
SELECT Id,Name=CreateDate=Max(CreateDate) from Items group by Id,Name
Now since I always use views for this kind of thing I do stand to be corrected on the first point!

EF creating an unwanted field in database

I've hit a snag while building a .net mvc site. I have 2 related objects and am struggling with properly linking them. Specifically:
public class Address
{
public int AddressId { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostCode { get; set; }
[ForeignKey("AddressCategory")] // <-- EF adds field to below object's table
public int AddressCategoryId { get; set; }
public virtual AddressCategory AddressCategory { get; set; }
}
public class AddressCategory
{
public int AddressCategoryId { get; set; }
public string Description { get; set; }
}
Adding the [ForeignKey] data annotation to the Address object results in EF adding an Address_AddressId column to the AddressCategory table, which I don't want (or need) to happen.
I've tried to omit the ForeignKey attribute, but then I run into other errors because .net can't link the tables (e.g. Unknown column 'Extent1.AddressId' in 'field list'). Additionally, I wouldn't be able to use:
var addresses = db.Addresses.Include(l => l.AddressCategory);
Is there any way to link the 2 tables without EF adding an additional column to the AddressCategory table?
Thank you to #cloudikka for responding. After much trial-and-error I seem to have gotten it to work simply by omitting any ForeignKey reference from either object. I let EF rebuild the database and perform all scaffolding (CRUD forms) and they have been created perfectly.
My take-away is that foreign key attributes should be used for parent-child relationships, but not for look-up tables. I clearly have much to learn about asp.net mvc!

Entity Framework POCO Does Not Fit Nicely with Domain Objects

I have taken a model first approach for a project i'm working on. An example of a class relationship is shown as follows, pretty strightforward:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
List<Photo> Photos { get; set; }
}
public class Photo
{
public int Id { get; set; }
public string Path { get; set; }
}
The database schema will roughly be:
--------------
Products Table
--------------
Id int,
Name Varchar
------------
Photos Table
------------
Id int,
Path varchar
ProductId int FK Products.ID
A Product can have Zero or more Photos.
Now when i try to plug is my ORM of choice (Entity Framework V4 - Poco approach) iam forced to map my relationships in the domain model!
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
List<Photo> Photos { get; set; }
}
public class Photo
{
public int Id { get; set; }
public string Path { get; set; }
public int ProductId {get; set; } //Foriegn Key
public Product Proudct {get; set; } //For uni-directional navigation
}
Firstly, i dont need/want uni-directional navigation. I understand this can be deleted. Secondly, I dont want the Foriegn Key declared in the Photos class.
I dont think this is true POCO/persistence ignorance if i must define database properties in the Domain Objects?
Do other ORM's behave this way?
I found the answer. Using the wizard, there is an option to "Include foreign key columns in the model" - Uncheck this box and you will a clean conceptual model without FK.
Make sure Code Generation Strategy is set to none in the properties window.
Why don't you want to have Photo.Product property? If there is no such property, it seems one photo can belong to several products and since database schema should be more complex (with auxiliary table).
The relationships don't have to be two-way, and don't have to be public (if you use true POCOs, not proxy types). You've said quite a bit about what you don't want in your code, but can you be clearer about how you do want to define the relationships? It has to go somewhere. Where would you like to put it? There are many options.