Asp.net mvc 到多个表的Linq映射

Asp.net mvc 到多个表的Linq映射,asp.net-mvc,Asp.net Mvc,我正在阅读一本关于“Pro ASP.NET MVC Framework”(Pro ASP.NET MVC Framework)的书,在一个示例中,作者使用linq创建了一个指向db表(以及一个伪存储库)的链接,如下所示:- using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Linq.Mapping; namespace DomainMod

我正在阅读一本关于“Pro ASP.NET MVC Framework”(Pro ASP.NET MVC Framework)的书,在一个示例中,作者使用linq创建了一个指向db表(以及一个伪存储库)的链接,如下所示:-

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq.Mapping;

namespace DomainModel.Entities
{
    [Table(Name = "Products")]
    public class Product
    {
        [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
        public int ProductID { get; set; }

        [Column] public string Name { get; set; }
        [Column] public string Description { get; set; }
        [Column] public decimal Price { get; set; }
        [Column] public string Category { get; set; }
        public string this[string propName]
        {
          get {
            if ((propName == "Name") && string.IsNullOrEmpty(Name))
                return "Please enter a product name";
            if ((propName == "Description") && string.IsNullOrEmpty(Description))
                return "Please enter a description";
            if ((propName == "Price") && (Price < 0))
                return "Price must not be negative";
            if ((propName == "Category") && string.IsNullOrEmpty(Category))
                return "Please specify a category";
            return null;
        }
    }
    public string Error { get { return null; } } // Not required    }
}

假存储库(不包括)和真实的DB连接存储库:-

using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DomainModel.Abstract;
using System.Data.Linq;
using DomainModel.Entities;

namespace DomainModel.Concrete
{
    public class SqlProductsRepository : IProductsRepository
    {
        private Table productsTable;
        public SqlProductsRepository(string connectionString)
        {
            productsTable = (new DataContext(connectionString)).GetTable();
        }

        public IQueryable Products
        {
            get { return productsTable; }
        }

        public void SaveProduct(Product product)
        {
            EnsureValid(product, "Name", "Description", "Category", "Price");

            // If it's a new product, just attach it to the DataContext
            if (product.ProductID == 0)
                productsTable.InsertOnSubmit(product);
            else {
                // If we're updating an existing product, tell the DataContext
                // to be responsible for saving this instance
                productsTable.Attach(product);
                // Also tell the DataContext to detect any changes since the last save
                productsTable.Context.Refresh(RefreshMode.KeepCurrentValues, product);
            }

            productsTable.Context.SubmitChanges();
        }

        public void DeleteProduct(Product product)
        {
            productsTable.DeleteOnSubmit(product);
            productsTable.Context.SubmitChanges();
        }

        private void EnsureValid(IDataErrorInfo validatable, params string[] properties)
        {
            if (properties.Any(x => validatable[x] != null))
                throw new InvalidOperationException("The object is invalid.");
        }
    }
转到具有指定列名的DB表“Products”,它工作得很好。我正在现实世界的应用程序中使用这种技术,因为它可以很好地处理DB访问层,但我需要能够从我的对象访问多个表。我如何做到这一点?我是否需要将我的对象拆分为反映其表的层次结构,或者我是否可以从主对象访问多个表,并将其他具有自己表的附加对象挂起?如果是这样,那么如何在对象和表之间创建ORM链接

干杯


MH

只需将相关表添加到您的存储库界面,就像您为产品所做的那样,然后在您的存储库类中创建具体的实现,就像您为产品所做的一样

我在我的应用程序上使用了相同的模式,我有两个存储库,每个存储库处理5-10个表。有两组不同的表是相关的,因此有两个存储库

我将更改SQLRepository构造函数,如下所示:

    public SqlProductsRepository(string connectionString)
    {
        DataContext dc = new DataContext(connectionString);
        productsTable = dc.GetTable<Product>();
    }
公共SqlProductsRepository(字符串连接字符串) { DataContext dc=新的DataContext(connectionString); productsTable=dc.GetTable(); } 然后,您可以轻松地对其进行扩展,例如:

    private Table<Order> ordersTable;

    public SqlProductsRepository(string connectionString)
    {
        DataContext dc = new DataContext(connectionString);
        productsTable = dc.GetTable<Product>();
        ordersTable = dc.GetTable<Order>();
    }

    IQueryable<Order> Orders
    {
        get { return from o in ordersTable select o; }
    }
私有表ordersTable;
公共SqlProductsRepository(字符串连接字符串)
{
DataContext dc=新的DataContext(connectionString);
productsTable=dc.GetTable();
ordersTable=dc.GetTable();
}
易货订单
{
获取{在ordersTable中从o返回选择o;}
}
编辑-回复评论

下面是如何通过此方法传递从属对象(相关表)的示例:

[Table(Name="Projects")]
public class Project
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
    public Guid ID { get; set; }
    [Column]
    public String Name { get; set; }
    [Column]
    public bool Active { get; set; }

    [Association(ThisKey="ID", OtherKey = "ProjectID")]
    private EntitySet<ProjectDate> _projectDates = new EntitySet<ProjectDate>();
    public IQueryable<ProjectDate> ProjectDates
    {
        get { return _projectDates.AsQueryable(); }
    }
}
[表(Name=“项目”)]
公共类项目
{
[列(IsPrimaryKey=true,IsDbGenerated=true,AutoSync=AutoSync.OnInsert)]
公共Guid ID{get;set;}
[专栏]
公共字符串名称{get;set;}
[专栏]
公共bool活动{get;set;}
[关联(ThisKey=“ID”,OtherKey=“ProjectID”)]
私有EntitySet_projectDates=新EntitySet();
公共可查询项目日期
{
获取{return\u projectDates.AsQueryable();}
}
}
以及ProjectDate类的完整性

[Table(Name="ProjectDates")]
public class ProjectDate
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
    public Guid ID { get; set; }
    [Column]
    public Guid ProjectID { get; set; }
    [Column]
    public DateTime TargetDate { get; set; }
    [Column(CanBeNull = true)]
    public DateTime? ActualDate { get; set; }
    [Column(CanBeNull=true, IsDbGenerated = true)]
    public DateTime? Created { get; set; }

    private EntityRef<Project> _project;
    [Association(ThisKey = "ProjectID", Storage = "_project", OtherKey = "ID")]
    public Project Project
    {
        get { return _project.Entity; }
        set { _project.Entity = value; ProjectID = _project.Entity.ID; }
    }
}
[表(Name=“ProjectDates”)]
公共类项目日期
{
[列(IsPrimaryKey=true,IsDbGenerated=true,AutoSync=AutoSync.OnInsert)]
公共Guid ID{get;set;}
[专栏]
公共Guid项目ID{get;set;}
[专栏]
public DateTime TargetDate{get;set;}
[列(CanBeNull=true)]
公共日期时间?实际日期{get;set;}
[列(CanBeNull=true,IsDbGenerated=true)]
公共日期时间?已创建{get;set;}
私人实体REF_项目;
[关联(ThisKey=“ProjectID”,Storage=“\u project”,OtherKey=“ID”)]
公共工程项目
{
获取{return\u project.Entity;}
设置{{u project.Entity=value;projectd={u project.Entity.ID;}
}
}

谢谢。对不起,我太傻了。如何在主对象中创建两个表之间的关系(例如,您可以访问产品的订单集合,例如product.orders非常感谢,我有一些UI代码要编写,但随后我会继续尝试。谢谢,开始工作了。我遇到了一个问题,使我陷入了&$%^$^^%^$*%的困境-我得到了一个“指定的转换无效”错误,我认为是AsQueryable->IQueryable部分,但经过反复的抱怨和戳,我发现这是由于db中的一个浮点被拉到应用程序中的一个浮点变量中造成的——你知道为什么会抛出错误吗?数据库数据类型和C#数据类型之间似乎没有奇偶性。如果我没记错的话我不得不对SQL浮点使用十进制,但这实际上可能有点过头了。它似乎在AsQueryable调用中抛出错误,只是因为LINQ在此之前没有执行,大多数在设计时未捕获的LINQ错误只会出现在您第一次尝试访问数据的代码行中,即使实际错误可能在LINQ查询中如果你只是想,一定有一个关于不同数据类型的表,你瞧,SQL浮点是C#double!
[Table(Name="ProjectDates")]
public class ProjectDate
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
    public Guid ID { get; set; }
    [Column]
    public Guid ProjectID { get; set; }
    [Column]
    public DateTime TargetDate { get; set; }
    [Column(CanBeNull = true)]
    public DateTime? ActualDate { get; set; }
    [Column(CanBeNull=true, IsDbGenerated = true)]
    public DateTime? Created { get; set; }

    private EntityRef<Project> _project;
    [Association(ThisKey = "ProjectID", Storage = "_project", OtherKey = "ID")]
    public Project Project
    {
        get { return _project.Entity; }
        set { _project.Entity = value; ProjectID = _project.Entity.ID; }
    }
}