实体框架 4 可以处理两个不同的数据源吗?

发布于 2024-12-03 05:02:06 字数 1699 浏览 1 评论 0原文

首先,了解一点背景信息

我有一个使用 Paradox 数据库的桌面应用程序,并且正在使用 SQL Server 开发一个新的 ASP.NET 应用程序来替换当前的桌面应用程序。

过渡将分三个阶段进行。 Web 应用程序的第一个版本将同时使用 SQL Server 和 Paradox。旧实体数据将来自 Paradox,新实体数据将来自 SQL Server。因此,该应用程序的桌面版和网页版可以互换使用。

在第二阶段,Paradox 中的所有数据都将导入到 SQL Server。旧的桌面应用程序(和 Paradox 数据库)将不再使用。

现在,技术问题

想象一个具有两个实体的简单模型:

public class Customer
{
    public Int32 ID { get; set; }
    public String Name { get; set; }

    virtual public IList<User> MyUsers { get; set; }
}

public class User
{
    public Int32 ID { get; set; }
    public String Name { get; set; }

    virtual public Customer MyCustomer { get; set; }
}

public class SqlServerContext : DbContext
{
    public SqlServerContext()
    {
        base.Configuration.ValidateOnSaveEnabled = false;
        base.Configuration.LazyLoadingEnabled = true;
        base.Configuration.ProxyCreationEnabled = true;
        base.Configuration.AutoDetectChangesEnabled = true;
    }
    public DbSet<User> Users { get; set; }
    public DbSet<Customer> Customers { get; set; }
}

当我对两个实体仅使用 SQL Server 时,一切工作正常。但现在我想从 Paradox 检索客户数据,从 SQL Server 检索用户数据。

然后,我为客户创建一个存储库,其中包含使用 Paradox 提供程序的底层 OleDbConnection。当然,实体框架仍然在 SQL Server 中创建 Customers 表,因为 User 有一个 Customer 属性。

然后,我删除了用户和客户之间的数据库关系 (FK)。现在我可以插入与客户相关的用户,即使它们位于不同的数据库中。

问题是:当我尝试从数据库检索用户时[例如:context.Users.Find(id)]我可以读取用户的ID和名称,但user.Customer为空。我希望通过 user.Customer.ID 属性获取客户 ID,因为此数据位于 SQL Server 的 Users 表中。

我走的路是对的吗?如果是,EF如何为用户带来客户ID?

如果没有,对于这种情况,什么是一个好的方法?我不想在模型中公开外键属性(即:我不想在 User 实体中拥有 int CustomerId 属性)。

提前致谢!

First, a little bit of context

I have one desktop application which uses a Paradox database and I am developing a new ASP.NET application using SQL Server to replace the current desktop app.

The transition will happen in tho phases. The first version of the web app will use SQL Server and Paradox at the same time. Legacy entities data will come from Paradox and data from new entities will come from SQL Server. So the desktop and web versions of the app can be used interchangeably.

In the second phase all data from Paradox will be imported to SQL Server. The old desktop app (and the Paradox db) won't be used anymore.

Now, the technical question

Imagine a simple model with two entities:

public class Customer
{
    public Int32 ID { get; set; }
    public String Name { get; set; }

    virtual public IList<User> MyUsers { get; set; }
}

public class User
{
    public Int32 ID { get; set; }
    public String Name { get; set; }

    virtual public Customer MyCustomer { get; set; }
}

public class SqlServerContext : DbContext
{
    public SqlServerContext()
    {
        base.Configuration.ValidateOnSaveEnabled = false;
        base.Configuration.LazyLoadingEnabled = true;
        base.Configuration.ProxyCreationEnabled = true;
        base.Configuration.AutoDetectChangesEnabled = true;
    }
    public DbSet<User> Users { get; set; }
    public DbSet<Customer> Customers { get; set; }
}

When I use only SQL Server for both entities everything works fine. But now I want to retrieve customer data from Paradox and user data from SQL Server.

I then create a repository for the customers, with an underlying OleDbConnection using the Paradox provider. Of course, Entity Framework still creates the Customers table in SQL Server, since User has a Customer property.

I then removed the database relationship (FK) between User and Customer. Now I am able to insert a User related to a Customer, even though they're in different databases.

The problem is: when I try to retrieve a user from db [eg: context.Users.Find(id)] I can read the user's ID and Name, but user.Customer is null. I expected to get the customer ID through the user.Customer.ID property, since this data is in the Users table in SQL Server.

Am I going to the right path? If so, how can EF bring the customer ID for the user?

And if not, what would be a good approach for this scenario? I don't want to expose foreign key properties in the model (i.e: i don't want to have a int CustomerId property in the User entity).

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独木成林 2024-12-10 05:02:06

当您访问user.MyCustomer时,EF将向Customers表发出一条select语句,然后具体化一个Customer对象。但在您的情况下,该表是空的或不存在。

您可以做的是在 User 类上包含标量属性 CustomerID

public class User
{
    public Int32 ID { get; set; }
    public String Name { get; set; }

    public int? CustomerID { get; set; }//assuming the db column name is also CustomerID
    virtual public Customer MyCustomer { get; set; }
}

然后按如下所示映射关系

public class SqlServerContext : DbContext
{
    public SqlServerContext()
    {
        base.Configuration.ValidateOnSaveEnabled = false;
        base.Configuration.LazyLoadingEnabled = true;
        base.Configuration.ProxyCreationEnabled = true;
        base.Configuration.AutoDetectChangesEnabled = true;
    }
    public DbSet<User> Users { get; set; }
    public DbSet<Customer> Customers { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       modelBuilder.Entity<User>()
       .HasOptional(u => u.User)
       .WithMany(c => c.MyUsers)
       .HasForeignKey(u => u.CustomerID);

    }
}

然后您可以使用 user.CustomerID 访问客户 ID 属性code> 而不是 user.Customer.ID

When you access user.MyCustomer, EF will issue a select statement to the Customers table and then materialize a Customer object. But in your case the table is empty or non existent.

What you can do is include a scalar property CustomerID on User class

public class User
{
    public Int32 ID { get; set; }
    public String Name { get; set; }

    public int? CustomerID { get; set; }//assuming the db column name is also CustomerID
    virtual public Customer MyCustomer { get; set; }
}

Then map the relationship as follows

public class SqlServerContext : DbContext
{
    public SqlServerContext()
    {
        base.Configuration.ValidateOnSaveEnabled = false;
        base.Configuration.LazyLoadingEnabled = true;
        base.Configuration.ProxyCreationEnabled = true;
        base.Configuration.AutoDetectChangesEnabled = true;
    }
    public DbSet<User> Users { get; set; }
    public DbSet<Customer> Customers { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       modelBuilder.Entity<User>()
       .HasOptional(u => u.User)
       .WithMany(c => c.MyUsers)
       .HasForeignKey(u => u.CustomerID);

    }
}

Then you can access the customer ID property using user.CustomerID instead of user.Customer.ID.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文