简体   繁体   中英

Linq to SQL column computed from query to different table?

Is it possible to define a column in one of my Linq to SQL entities such that it's calculated as part of the SQL query?

Here is my Entity class so far:

[Table(Name = "Products")]
public class ProductEntity
{
    [Column(Name = "ModelNumber", IsPrimaryKey = true)]
    public string ModelNumber { get; set; }

    [Column(Name = "SerialNumber", IsPrimaryKey = true)]
    public string SerialNumber { get; set; }
}

I want to add a new property like:

[Column]
public bool ActiveListing { get; set; }

Except its value should be calculated based on a complicated Linq query which I am executing elsewhere right now (not in SQL!):

context.GetTable<SalesRecords>().
    Where(ah => ah.Date <= GlobalCoordinatedDateTime.Local).
    Where(ah => ah.ProductModelNumber == ModelNumber && ah.ProductSerialNumber == SerialNumber).
    OrderByDescending(ah => ah.Date).
    FirstOrDefault().Status == Statuses.Active;

My best guess is that I could use AssociationAttribute but I don't know how to do that when there could be more than one match in the "SalesRecords" table and I want to get the first after applying some ordering.

EDIT: My question is not the same as a simple "computed column" as seen in this question , I need to compute the value using data stored in different tables, outside of the entity its self.

if you don't need to store the column at database you can use:

[Table(Name = "Products")]
public class ProductEntity
{
    // your other columns...

    [NotMapped]
    public bool ActiveListing {
        get
        {
            bool result = false;

            // your logic to calculate then set to "result" variable

            return result;
        }
    }

}

but if you need to store it, change the name of ActiveListing property, then manually assign to the final ActiveListing property before you will create or update the record. Example:

[Table(Name = "Products")]
public class ProductEntity
{
    // your other columns...

    [NotMapped]
    public bool CalculateActiveListing
    {
        get
        {
            bool result = false;

            // your logic to calculate then set to "result" variable

            return result;
        }
    }

    public bool ActiveListing { get; set; }
}

here an example if you have a navigation property to SalesRecords. important have Lazy Loading enabled, or use the Include() method.

    [NotMapped]
    public bool CalculateActiveListing
    {
        get
        {
            bool result = false;

            // your logic to calculate then set to "result" variable.
            // for example:

            // validate SalesRecords has data
            if (this.SalesRecords != null)
            {
                var sale = this.SalesRecords
                    .Where(ah => ah.Date <= GlobalCoordinatedDateTime.Local)
                    .Where(ah => ah.ProductModelNumber == ModelNumber && ah.ProductSerialNumber == SerialNumber)
                    .OrderByDescending(ah => ah.Date)
                    .FirstOrDefault();

                // sale exists
                if (sale != null)
                {
                    result = sale.Status == Statuses.Active;
                }
            }

            return result;
        }
    }

another example using your DbContext:

    [NotMapped]
    public bool CalculateActiveListing
    {
        get
        {
            bool result = false;

            // your logic to calculate then set to "result" variable.
            // for example:

            using (var context = new MyDbContext())
            {
                var sale = context.SalesRecords
                    .Where(ah => ah.Date <= GlobalCoordinatedDateTime.Local)
                    .Where(ah => ah.ProductModelNumber == ModelNumber && ah.ProductSerialNumber == SerialNumber)
                    .OrderByDescending(ah => ah.Date)
                    .FirstOrDefault();

                // sale exists
                if (sale != null)
                {
                    result = sale.Status == Statuses.Active;
                }
            }

            return result;
        }
    }

sorry, my bad english.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM