【问题标题】:Linq get random row (one to many) and assign that to a variable/list?Linq 获取随机行(一对多)并将其分配给变量/列表?
【发布时间】:2013-12-02 01:37:59
【问题描述】:

我有一个这样设计的模型:

public class SearchListing
{
    public int property_id { get; set; }
    public int office_property_id { get; set; }
    public String office_property_description { get; set; }
    public String property_name { get; set; }
    public String property_street { get; set; }
    public String property_city { get; set; }
    public String property_state { get; set; }
    public String property_zip { get; set; }
    public Nullable<int> numBedrooms { get; set; }
    public Nullable<int> numBathrooms { get; set; }
    public bool numGarages { get; set; }
}

我打算使用一个 linq 语句来填充这个模型。该模型可以单独使用,也可以有一个搜索列表列表。我的 linq 语句必须能够检索符合条件的所有属性。

属性与 officeproperties 具有一对多的关系。因此,一个物业可能有多个关于该物业的办公室特定信息。我想随机选择其中一个办公室来提供他们有关该物业的信息。我有以下 linq:

propertyIDSearch = (from p in db.Property
                    join bp in db.OfficeProperty on p.property_id equals bp.property_id 
                    join b in db.Office on bp.office_id equals b.office_id                                                                                
                    where b.status == 1 && bp.active_listing == true
                    orderby Guid.NewGuid()    
                    select new SearchListing
                    {
                        property_id = p.property_id,
                        office_property_id = bp.office_property_id,
                        office_property_description  = bp.description,
                        property_name = p.prop_name,
                        property_street = p.street,
                        property_city = p.city,
                        property_state = p.state,
                        property_zip = p.zip,
                        numBedrooms = p.bed_rooms,
                        numBathrooms = p.baths,
                        numGarages = p.garage
                    })
                   .Take(1)
                   .ToList<SearchListing>();  

这可行,但只给了我一个属性。我正在考虑执行以下操作,但后来我无法在语句中使用 p.property_id:

propertyIDSearch = (from p in db.Property
                    select new SearchListing
                    {
                        property_id = p.property_id,
                        office_property_id = (from bp in OfficeProperty
                                              join b in Office on b.office_id equals bp.office_id
                                              where p.property_id equals bp.property_id 
                                              select bp.office_property_id)
                        office_property_description = bp.description,
                        property_name = p.prop_name,
                        property_street = p.street,
                        property_city = p.city,
                        property_state = p.state,
                        property_zip = p.zip,
                        numBedrooms = p.bed_rooms,
                        numBathrooms = p.baths,
                        numGarages = p.garage
                    })
                   .ToList<SearchListing>(); 

该代码不起作用,只是为了显示思考过程而编写的。我需要使用该特定属性的办公室的一个随机实例填写办公室属性描述和办公室属性 ID。如果我像刚才那样在 select 语句中运行 linq,我就不能使用该实例来获取描述。如果我尝试在加入中添加,我将无法使用 p.property id:

propertyIDSearch = (from p in db.Property
                    join bp in (from bp in OfficeProperty
                                join b in Office on b.office_id equals bp.office_id 
                                where p.property_id equals bp.property_id
                                select bp).ToList()[new Random().Next(list.count)] on p.property_id equals bp.property_id                                             
                    select new SearchListing
                    {
                        property_id = p.property_id,
                        office_property_id = bp.office_property_id
                        office_property_description  = bp.description,
                        property_name = p.prop_name,
                        property_street = p.street,
                        property_city = p.city,
                        property_state = p.state,
                        property_zip = p.zip,
                        numBedrooms = p.bed_rooms,
                        numBathrooms = p.baths,
                        numGarages = p.garage
                    })
                   .ToList<SearchListing>(); 

这也不起作用。

编辑:

我根据提供的建议进行了尝试,这似乎有效。这种方法有什么不好的地方吗?

propertyIDSearch = (from p in db.Property
                                        join bp in db.OfficeProperty on p.property_id equals bp.property_id
                                        where bp.Officeproperty_id == (from bp2 in db.OfficeProperty
                                                                        join b in db.Office on bp2.Office_id equals b.Office_id
                                                                        where b.status == 1 && bp2.active_listing == true && bp2.property_id == p.property_id
                                                                        orderby Guid.NewGuid()
                                                                        select bp2.Office_property_id).Take(1).FirstOrDefault()
                                        //Build the where clauses based off of the search criteria
                                        where p.property_id == (searchCriteria.propertyID > 0 ? searchCriteria.propertyID : p.property_id)                                        
                                        where p.geography_id == (searchCriteria.citySelected > 0 ? searchCriteria.citySelected : p.geography_id)
                                        select new SearchListing
                                        {
                                            property_id = p.property_id,
                                            Office_property_id = bp.Office_property_id,
                                            Office_property_description = bp.description,
                                            property_name = p.prop_name,
                                            property_street = p.street,
                                            property_city = p.city,
                                            property_state = p.state,
                                            property_zip = p.zip,
                                            numBedrooms = p.bed_rooms,
                                            numBathrooms = p.baths,
                                            numGarages = p.garage
                                        }).ToList<SearchListing>();

【问题讨论】:

  • 我修改了我的代码,你介意看看吗?

标签: c# .net asp.net-mvc linq entity-framework


【解决方案1】:

你好,为什么不包括一个属性而不是一个 office_property_id

public OfficeProperty OfficeProperty; 

在 SearchListing 上。

而不是加入为什么不使用这样的虚拟财产:

public virtual ICollection<OfficeProperty> OfficeProperties;

对于办公室:

public Office Office;

在选择属性类时,您可以这样做:

var rand = new Random();

propertyIDSearch = (from p in db.Property.Include(op => op.OfficeProperties).Include(o => o.Office)                                                                            
                where p.Office.status == 1 && p.OfficeProperties.where(op => op.active_listing == true).Any()
                orderby Guid.NewGuid()    
                select new SearchListing
                {
                    property_id = p.property_id,
                    OfficeProperty = p.OfficeProperties[rand.Next(p.OfficeProperties.Count())] // you can get the description inside this properties...
                    property_name = p.prop_name,
                    property_street = p.street,
                    property_city = p.city,
                    property_state = p.state,
                    property_zip = p.zip,
                    numBedrooms = p.bed_rooms,
                    numBathrooms = p.baths,
                    numGarages = p.garage
                })
               .Take(1)
               .ToList<SearchListing>();

不需要连接..这是创建 EF 的原因之一..减少代码..

【讨论】:

    【解决方案2】:

    试试这个:

    var rnd = new Random();
    
    var idPairs = (
            from p in db.Property
            join bp in db.OfficeProperty on p.property_id equals bp.property_id
            join b in db.Office on bp.office_id equals b.office_id
            where b.status == 1 && bp.active_listing == true
            select new { p.property_id, b.office_id }
        )
            .ToLookup(x => x.property_id, x => x.office_id)
            .Select(x => new
            {
                property_id = x.Key,
                office_id = x.ElementAt(rnd.Next(0, x.Count())),
            })
            .ToArray();
    
    var idPair = idPairs.ElementAt(rnd.Next(0, idPairs.Count()));
    

    这应该会为您提供一个随机选择的房产和该房产的随机选择的办公室。 (如果我不了解您的选择要求,请告诉我。)

    然后像这样进行最终查询:

    var propertyIDSearch = (
            from p in db.Property
            join bp in db.OfficeProperty on p.property_id equals bp.property_id
            join b in db.Office on bp.office_id equals b.office_id
            where p.property_id == idPair.property_id
            where b.office_id == idPair.office_id 
            select new SearchListing
            {
                property_id = p.property_id,
                office_property_id = bp.office_property_id,
                office_property_description  = bp.description,
                property_name = p.prop_name,
                property_street = p.street,
                property_city = p.city,
                property_state = p.state,
                property_zip = p.zip,
                numBedrooms = p.bed_rooms,
                numBathrooms = p.baths,
                numGarages = p.garage
            }
        )
        .ToList();
    

    【讨论】:

    • 带有 idpairs 的第一段代码以 ID 对结束。我希望它选择多个属性,即我可以搜索所有 500 个属性,并且这 500 个属性中的每一个都将存储在 SearchListing 中,每个属性都有一个与所选属性相关联的随机办公室。我猜它不会对你的代码有太大的改变,我只是用 idPairs 替换 idPair 吗?
    • 这样的两个查询也会对 SQL 数据库不利吗?
    • 它确实改变了代码。您不能对内存中的集合和数据库列表进行连接。为此,您必须将整个数据库放入内存中。您唯一能做的就是在内存集合上使用Contains 扩展方法,因为它适用于数据库调用。然后,您将分别将您的属性和办公室属性集合引入内存,然后在那里进行连接。您将对数据库进行三个调用,如果不将整个内容加载到内存中,我认为您无法改进它。
    • 我在编辑中添加了另一个语句,您介意看一下吗?
    【解决方案3】:

    我有示例代码,也许可以帮助你:

    1.模型设计表:

    public class OfficeProperty
    {
        public int office_property_id { get; set; }
        public int property_id { get; set; }
        public int office_id { get; set; }
        public string description { get; set; }
    }
    
    public class Office
    {
        public int office_id { get; set; }
        public String office_name { get; set; }
    }
    
    public class Property
    {
        public int property_id { get; set; }
        public string property_name { get; set; }
    }
    

    2。查看设计表:

    public class SearchListing
    {
        public int office_property_id { get; set; }
        public string description { get; set; }
        public int property_id { get; set; }
        public string property_name { get; set; }
        public int office_id { get; set; }
        public string office_name { get; set; }
    }
    

    3.样本数据表:

    List<Property> dbProperty = new List<Property>();
    Property _p;
    
    _p = new Property();
    _p.property_id = 1;
    _p.property_name = "guitar";
    dbProperty.Add(_p);
    
    _p = new Property();
    _p.property_id = 2;
    _p.property_name = "bass";
    dbProperty.Add(_p);
    
    _p = new Property();
    _p.property_id = 3;
    _p.property_name = "drum";
    dbProperty.Add(_p);
    
    _p = new Property();
    _p.property_id = 4;
    _p.property_name = "banana";
    dbProperty.Add(_p);
    
    _p = new Property();
    _p.property_id = 5;
    _p.property_name = "apel";
    dbProperty.Add(_p);
    
    
    List<Office> dbOffice = new List<Office>();
    Office _b;
    
    _b = new Office();
    _b.office_id = 1;
    _b.office_name = "music";
    dbOffice.Add(_b);
    
    _b = new Office();
    _b.office_id = 1;
    _b.office_name = "fruit";
    dbOffice.Add(_b);
    
    
    List<OfficeProperty> dbOfficeProperty = new List<OfficeProperty>();
    OfficeProperty _bp;
    
    _bp = new OfficeProperty();
    _bp.office_property_id = 1;
    _bp.property_id = 1;
    _bp.office_id = 1;
    _bp.description = "property office music";
    dbOfficeProperty.Add(_bp);
    
    _bp = new OfficeProperty();
    _bp.office_property_id = 2;
    _bp.property_id = 2;
    _bp.office_id = 1;
    _bp.description = "property office music";
    dbOfficeProperty.Add(_bp);
    
    _bp = new OfficeProperty();
    _bp.office_property_id = 3;
    _bp.property_id = 3;
    _bp.office_id = 1;
    _bp.description = "property office music";
    dbOfficeProperty.Add(_bp);
    
    _bp = new OfficeProperty();
    _bp.office_property_id = 4;
    _bp.property_id = 4;
    _bp.office_id = 2;
    _bp.description = "property office fruit";
    dbOfficeProperty.Add(_bp);
    
    _bp = new OfficeProperty();
    _bp.office_property_id = 5;
    _bp.property_id = 5;
    _bp.office_id = 2;
    _bp.description = "property office fruit";
    dbOfficeProperty.Add(_bp);
    

    4.林Q:

    List<SearchListing> propertyIDSearch  = 
        (from bp in dbOfficeProperty
        join p in dbProperty on bp.property_id equals p.property_id
        join b in dbOffice on bp.office_id equals b.office_id
        select new SearchListing
        {
            office_property_id = bp.office_property_id,
            description = bp.description,
            property_id = p.property_id,
            property_name = p.property_name,
            office_id = b.office_id,
            office_name = b.office_name
        }).OrderBy(r => Guid.NewGuid()).Take(1).ToList<SearchListing>();
    

    5.结果:

    -- 1 record random
    ----------------------------------------------------------------------------------------------------
    office_property_id | description            | property_id | property_name | office_id | office_name
    ----------------------------------------------------------------------------------------------------
           1           | property office music  |      1      |    guitar     |     1     |  music
    ----------------------------------------------------------------------------------------------------
    
    -- all record (5)
    ----------------------------------------------------------------------------------------------------
    office_property_id | description            | property_id | property_name | office_id | office_name
    ----------------------------------------------------------------------------------------------------
           1           | property office music  |      1      |    guitar     |     1     |  music
           2           | property office music  |      2      |    bass       |     1     |  music
           3           | property office music  |      3      |    drum       |     1     |  music
           4           | property office fruit  |      4      |    banana     |     2     |  fruit
           5           | property office fruit  |      5      |    apel       |     2     |  fruit
    ----------------------------------------------------------------------------------------------------
    

    更新:12 月 5 日


    我修改了我的示例代码,也许可以帮助你:

    1.模型设计表:

    public class OfficeProperty
    {
        public int office_property_id { get; set; }
        public int property_id { get; set; }
        public string description { get; set; }
    }
    
    public class Property
    {
        public int property_id { get; set; }
        public string property_name { get; set; }
    }
    

    2。查看设计表:

    public class SearchListing1
    {
        public int property_id { get; set; }
        public string property_name { get; set; }
        public int office_property_id { get; set; }
        public string description { get; set; }
    }
    
    public class GroupOfficeProperty
    {
        public int property_id { get; set; }
        public int office_property_id { get; set; } 
    }
    

    3.样本数据表:

    List<Property> dbProperty = new List<Property>();
    Property _p;
    
    _p = new Property();
    _p.property_id = 1;
    _p.property_name = "guitar";
    dbProperty.Add(_p);
    
    _p = new Property();
    _p.property_id = 2;
    _p.property_name = "banana";
    dbProperty.Add(_p);
    
    
    List<OfficeProperty> dbOfficeProperty = new List<OfficeProperty>();
    OfficeProperty _bp;
    
    _bp = new OfficeProperty();
    _bp.office_property_id = 1;
    _bp.property_id = 1;
    _bp.description = "property office music";
    dbOfficeProperty.Add(_bp);
    
    _bp = new OfficeProperty();
    _bp.office_property_id = 2;
    _bp.property_id = 1;
    _bp.description = "property office electronic";
    dbOfficeProperty.Add(_bp);
    
    _bp = new OfficeProperty();
    _bp.office_property_id = 3;
    _bp.property_id = 2;
    _bp.description = "property office fruit";
    dbOfficeProperty.Add(_bp);
    
    _bp = new OfficeProperty();
    _bp.office_property_id = 4;
    _bp.property_id = 2;
    _bp.description = "property office food";
    dbOfficeProperty.Add(_bp);`enter code here`
    
    _bp = new OfficeProperty();
    _bp.office_property_id = 5;
    _bp.property_id = 2;
    _bp.description = "property office plan";
    dbOfficeProperty.Add(_bp);
    

    4.林Q:

    List<SearchListing1> propertyIDSearch =
        dbProperty
        .Select(p => new SearchListing1
            {
                property_id = p.property_id,
                property_name = p.property_name,
                office_property_id =
                    dbOfficeProperty
                    .OrderBy(r => Guid.NewGuid())
                    .Where(bp => bp.property_id == p.property_id)
                    .Take(1)
                    .FirstOrDefault().office_property_id
            })
        .Join(dbOfficeProperty, a1 => a1.office_property_id, a2 => a2.office_property_id,
            (a1, a2) => new SearchListing1
            {
                property_id = a1.property_id,
                property_name = a1.property_name,
                office_property_id = a1.office_property_id,
                description = a2.description
            })
        .ToList<SearchListing1>();
    

    5.结果:

    -- 2 record with 2 property and 2 office property random
    ----------------------------------------------------------------------------------------------------
    property_id |   property_name    | office_property_id |         description
    ----------------------------------------------------------------------------------------------------
         1      |     guitar         |         2          |  property office electronic
         2      |     banana         |         5          |  property office plan
    ----------------------------------------------------------------------------------------------------
    

    5.说明:

    -- get all property
        dbProperty
        .Select(p => new SearchListing1
            {
                property_id = p.property_id,
                property_name = p.property_name,
            })
    
    -- get office property with random record, filter by property id, 1 row and 1 field 
        string n = 
            dbOfficeProperty
            .OrderBy(r => Guid.NewGuid())
            .Where(bp => bp.property_id == 1)
            .Take(1)
            .FirstOrDefault().office_property_id.ToString();
    

    或者您可以更改您的代码:

    office_property_id = (from bp in OfficeProperty
                          join b in Office on b.office_id equals bp.office_id
                          where p.property_id equals bp.property_id 
                          select bp.office_property_id)
    

    改为:

    office_property_id = (from bp in OfficeProperty
                          join b in Office on b.office_id equals bp.office_id
                          where p.property_id equals bp.property_id 
                          orderby Guid.NewGuid()).FirstOrDefault().office_property_id
    

    【讨论】:

    • 这与我想要做的很接近。这对于一个财产来说很好,但我需要一个随机关联到一个附属于该财产的经纪人办公室的一堆财产的列表。因此,在您的示例中,您的五个办公室 ID 为 1 到 5,我可以有两个属性,其中一个具有办公室属性 1 和 2,第二个属性具有 3、4、5。返回的搜索列表将是属性 1,选择 officeproperty 1 或 2(这是随机的)和属性 2,选择 3、4、5。
    • 我在编辑中添加了另一个语句,您介意看一下吗?
    • 我对“.Join(dbOfficeProperty, a1 => a1.office_property_id, a2 => a2.office_property_id, (a1, a2) => new SearchListing1" 部分有点困惑,比如什么它在做什么?a1、a2 和 (a1,a2) 是什么?我不习惯使用 .select 之类的东西来查看 linq,我已经习惯了我写它的方式。不要假设你可以用那个写同样的东西吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    • 2021-05-06
    相关资源
    最近更新 更多